<?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>Embedded Development &amp; Programming Archives | DMC, Inc.</title>
	<atom:link href="https://static.dmcinfo.com/blog/category/embedded-development-programming/feed/index.xml" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Mon, 31 Aug 2026 14:34:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://static.dmcinfo.com/wp-content/uploads/2025/04/site-icon-150x150.png</url>
	<title>Embedded Development &amp; Programming Archives | DMC, Inc.</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Adapting Manufacturing Operations? Flexible PCB and PCBA Testing Is Key to Success </title>
		<link>https://static.dmcinfo.com/blog/44756/pcb-test-systems/</link>
		
		<dc:creator><![CDATA[Brent Hoerman]]></dc:creator>
		<pubDate>Tue, 09 Jun 2026 18:18:17 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<category><![CDATA[Product Development]]></category>
		<category><![CDATA[Test and Measurement Automation]]></category>
		<category><![CDATA[Manufacturing Test Solutions]]></category>
		<category><![CDATA[PCB Testing]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=44756</guid>

					<description><![CDATA[<p>As manufacturing strategies evolve and production lines reshore to the United States, one challenge continues to come up for many companies: How do we make sure we can get reliable circuit board testing in a manufacturing setting? Testing does not have to be an afterthought or a necessary evil. When designed correctly, it becomes a [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/44756/pcb-test-systems/">Adapting Manufacturing Operations? Flexible PCB and PCBA Testing Is Key to Success </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As manufacturing strategies evolve and production lines reshore to the United States, one challenge continues to come up for many companies: How do we make sure we can get reliable circuit board testing in a manufacturing setting? Testing does not have to be an afterthought or a necessary evil. When designed correctly, it becomes a critical part of the quality strategy, supporting higher efficiency, improved yields, and cost savings across the production lifecycle.</p>



<p class="wp-block-paragraph">At DMC, we see these challenges firsthand through our work with a wide range of manufacturers in different industries. Our team designs custom test solutions that meet demanding performance requirements while remaining practical, cost-effective, and scalable. By focusing on adaptability and reliability, we help operators build test systems that support the needs of today while looking forward to tomorrow.</p>



<h2 class="wp-block-heading" id="h-why-testing-matters-more-than-ever"><strong>Why Testing Matters More Than Ever</strong></h2>



<p class="wp-block-paragraph">A well-designed PCB and PCBA test strategy does more than test products at the end of the line. It supports quality, throughput, and futureproofs manufacturing operations as they continue to scale and evolve:</p>



<ul class="wp-block-list">
<li><strong>Quality Assurance:</strong> Catch defects early to avoid costly downstream failures.</li>



<li><strong>Throughput Optimization:</strong> Keep your line moving without sacrificing accuracy.</li>



<li><strong>Compliance &amp; Traceability:</strong> Meet industry standards and maintain audit-ready records.</li>



<li><strong>Lifecycle Adaptability:</strong> Design systems that adapt as your product mix evolves.</li>
</ul>



<p class="wp-block-paragraph">There are many reasons today for manufacturers to take a flexible approach when building a test system. Flexibility allows manufacturers to balance precision with speed, validating each unit without bottlenecking production. Automated test solutions also enable constant measurement, surfacing issues before they impact final assembly or the field. This approach not only improves first-pass yield, it also shortens feedback loops.</p>



<p class="wp-block-paragraph" id="h-why-testing-matters-now-more-than-ever">It’s equally important that modern test platforms are built for change. As products evolve and regulations shift, operators need test systems that can scale easily, integrate new test points, and support expanded data collection without a full redesign every time. Flexible, software-driven architectures make it easier to maintain compliance and protect your testing investment.</p>



<h2 class="wp-block-heading" id="h-dmc-s-approach-expertise-flexibility">DMC&#8217;s Approach: Expertise + Flexibility</h2>



<p class="wp-block-paragraph">What sets DMC apart? Deep in-house expertise, industry certifications, and best practices, combined with strategic partnerships. We’ve built relationships with leading fixture manufacturers, instrumentation vendors, and automation specialists. This allows us to deliver end-to-end solutions tailored to your requirements, or any specific pieces of the system you need:</p>



<ul class="wp-block-list">
<li><strong>Fixturing Options:</strong> From full bed-of-nails (BoN) systems for high-volume lines, to cost-effective connector-based fixturing solutions for smaller runs.</li>



<li><strong>Instrumentation:</strong> Modular, serviceable, and upgradeable DAQ and rack-based instruments sourced from trusted partners, and selected based on your needs and requirements.</li>



<li><strong>Software:</strong> Several customizable platforms ready to deploy and meet your current and future needs.</li>



<li style="padding-bottom:var(--wp--preset--spacing--30)"><strong>Peripheral Systems:</strong> From simple barcode scanners, printers, &amp; PLC automation interfaces to add-on services like MES integration and analytics platform design and delivery.</li>
</ul>



<figure class="wp-block-image size-full is-resized" style="margin-bottom:var(--wp--preset--spacing--60)"><img fetchpriority="high" decoding="async" width="1073" height="236" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-1.png" alt="" class="wp-image-44772" style="width:1192px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-1.png 1073w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-1-300x66.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-1-1024x225.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-1-768x169.png 768w" sizes="(max-width: 1073px) 100vw, 1073px" /></figure>



<h2 class="wp-block-heading" id="h-fixturing-the-foundation-of-reliable-testing">Fixturing: The Foundation of Reliable Testing</h2>



<p class="wp-block-paragraph">Whether your Device Under Test (DUT) is a bare PCB, a PCB assembly, or a fully enclosed PCB, your connection strategy drives cost, reliability, and timing. DMC can offer consulting and execution for:</p>



<ul class="wp-block-list">
<li><strong>Complete Bed-of-Nails Fixtures:</strong> High-reliability, low-cost, or well-balanced systems can be sourced from multiple DMC partners.</li>



<li><strong>Cost-Sensitive Alternatives:</strong> DMC can offer in-house-designed and built fixturing or pogo-pin connector-based systems to reduce your spend.</li>



<li><strong>Automation Options:</strong> Robotic or auto-loading systems for high-throughput environments.</li>



<li style="padding-bottom:var(--wp--preset--spacing--30)"><strong>Flexibility for Low-Volume, High-Mix Assembly:</strong> Quick-change fixtures and adaptable test sequences.</li>
</ul>



<h2 class="wp-block-heading" id="h-test-system-architecture-built-for-your-needs">Test System Architecture: Built for Your Needs</h2>



<p class="wp-block-paragraph">Every system we design can be tailored to your application and include the components needed to support reliable, efficient testing, including:</p>



<ul class="wp-block-list">
<li><strong>DUT Connections &amp; Fixturing: </strong>Based on your project needs.</li>



<li><strong>Instrumentation:</strong> High-power, high-current, and high-voltage measurements are our specialty.</li>



<li><strong>Overall System Integration:</strong> Turn-key workbenches and/or racks with integrated fixtures and peripherals, to cost-saving, simple enclosure-based systems to add to your workbench.</li>



<li><strong>Software:</strong> Modular, intuitive GUIs that make operation simple, and test-engineering-friendly test sequence and parameter modification.</li>



<li><strong>Peripheral Integration:</strong> Barcode scanners, printers, databases, MES, analytics, and more.</li>
</ul>



<p class="wp-block-paragraph">For low-volume, high-mix operations, we can often recommend a single flexible test system that supports easy fixture changeovers and multiple DUT configurations, a real cost saver.</p>



<figure class="wp-block-image size-full is-resized" style="margin-bottom:var(--wp--preset--spacing--50)"><img decoding="async" width="1075" height="240" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-2.png" alt="" class="wp-image-44778" style="width:1200px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-2.png 1075w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-2-300x67.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-2-1024x229.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/05/flexible-pcb-pcba-testing-image-2-768x171.png 768w" sizes="(max-width: 1075px) 100vw, 1075px" /></figure>



<h3 class="wp-block-heading" id="h-advanced-capabilities"><strong>Advanced Capabilities</strong></h3>



<ul class="wp-block-list">
<li><strong>Multiplexing:</strong> Reduce instrumentation costs and/or support multi-DUT setups with smart switching topologies.</li>



<li><strong>Microcontroller Programming:</strong> Need PCBA flashing station capability in your test system? We’ve got you covered.</li>



<li><strong>Scalable Design:</strong> If needed, DMC’s flexible designs let you start small and expand as your needs grow.</li>



<li><strong>Non-Standard Measurements:</strong> From magnetic and optical sensing to RF and high-power applications, we take on complex PCBA test challenges others may avoid.</li>
</ul>



<h2 class="wp-block-heading" id="h-software-that-works-for-you">Software That Works for You</h2>



<p class="wp-block-paragraph">DMC software solutions are not one-size-fits-all; they’re built to deliver speed, flexibility, and futureproofing in one package. With ready-to-deploy base designs and a wide range of platform tools at our experts’ fingertips, we can get your custom application up and running quickly, reducing downtime and fortifying your system for the future. All of our platforms and tools are designed with future flexibility and integration in mind, helping to ensure system effectiveness as demand and technologies change:</p>



<ul class="wp-block-list">
<li><strong>Ready-to-Deploy:</strong> Base designs and a wide range of platform tools allow us to get your test software up and running quickly.</li>



<li><strong>Customizable:</strong> DMC can quickly add the software features you need now, while our modular platform tools allow you to grow as your requirements evolve.</li>



<li><strong>Future-Proof: </strong>All of our software platforms and tools are designed with your future flexibility and integration needs in mind.</li>
</ul>



<p class="wp-block-paragraph">We can also walk through GUI examples and provide live software demonstrations to show how powerful and intuitive our systems are. For a deeper look at one of our platforms, see <a href="https://static.dmcinfo.com/blog/39679/the-hidden-cost-of-one-off-test-systems/" target="_blank" rel="noreferrer noopener">The Hidden Cost of One-Off Test Systems</a>.</p>



<h2 class="wp-block-heading" id="h-why-choose-dmc-for-test-and-measurement-solutions">Why Choose DMC for Test and Measurement Solutions?</h2>



<p class="wp-block-paragraph">DMC has a proven track record with major US manufacturers, supporting their complex test and measurement challenges and shifting technology needs. With multiple regional offices across the country, DMC is able to provide coast-to-coast support wherever our clients operate.</p>



<p class="wp-block-paragraph">In addition to deep test and measurement expertise, our team also specializes in non-standard measurements and challenging test scenarios, partnering with leading instrumentation vendors to deliver reliable results.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">Whether our clients are looking for a complete, turnkey system or modular components that fit within an existing strategy, DMC adapts every approach to meet business goals and project needs.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step">Ready to optimize your testing? DMC can help you take the next step.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Contact DMC to discuss your project and learn how our <a href="https://static.dmcinfo.com/services/test-and-measurement-automation/">Test &amp; Measurement solutions</a> can support reshoring, test strategy upgrades, and more.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>



<div class="wp-block-group alignwide has-global-padding is-layout-constrained wp-container-core-group-is-layout-9243fccf wp-block-group-is-layout-constrained" style="margin-top:var(--wp--preset--spacing--70);margin-bottom:var(--wp--preset--spacing--70);padding-right:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--50)">
<h2 class="wp-block-heading alignwide has-text-align-left" id="h-related-work">Related Work</h2>



<div class="wp-block-cb-carousel-v2 alignwide cb-carousel-block" data-cb-slides-per-view="1" data-cb-slides-per-group="1" data-cb-space-between="15" data-cb-speed="300" data-cb-navigation="true" data-cb-pagination="true" data-cb-loop="true" data-cb-autoplay="true" data-cb-autoplay-speed="3000" data-cb-breakpoints="{&quot;768&quot;:{&quot;slidesPerView&quot;:3,&quot;slidesPerGroup&quot;:1}}"><div class="swiper"><div class="cb-wrapper swiper-wrapper">
<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-15285 our_work type-our_work status-publish has-post-thumbnail hentry work_category-automotive work_category-battery-pack-test-systems work_category-energy-and-utilities work_category-green-technology work_category-labview work_category-semiconductor work_category-test-measurement-automation work_category-test-stand">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/03/Bed-of-Nails-Battery-Management-System-PCB-Test-Station.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="Bed-of-Nails Battery Management System" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/03/Bed-of-Nails-Battery-Management-System-PCB-Test-Station.png 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/03/Bed-of-Nails-Battery-Management-System-PCB-Test-Station-300x107.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/03/Bed-of-Nails-Battery-Management-System-PCB-Test-Station-1024x366.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/03/Bed-of-Nails-Battery-Management-System-PCB-Test-Station-768x274.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-1 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/bed-of-nails-battery-management-system-pcb-test-station/" target="_self" >Bed-of-Nails Battery Management System PCB Test Station</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-14687 our_work type-our_work status-publish has-post-thumbnail hentry work_category-automotive work_category-embedded-development-programming work_category-labview work_category-product-development work_category-test-measurement-automation work_category-test-stand">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2019/03/Bed-of-Nails-PCB-Functional-Test-System-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="Bed of Nails PCB Functional Test System" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2019/03/Bed-of-Nails-PCB-Functional-Test-System-1.jpg 1400w, https://static.dmcinfo.com/wp-content/uploads/2019/03/Bed-of-Nails-PCB-Functional-Test-System-1-300x107.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2019/03/Bed-of-Nails-PCB-Functional-Test-System-1-1024x366.jpg 1024w, https://static.dmcinfo.com/wp-content/uploads/2019/03/Bed-of-Nails-PCB-Functional-Test-System-1-768x274.jpg 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-2 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/bed-of-nails-pcb-test-system/" target="_self" >Bed-of-Nails PCB Functional Test System, Automotive Gauge Cluster Controller</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-15318 our_work type-our_work status-publish has-post-thumbnail hentry work_category-automotive work_category-embedded-development-programming">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/End-of-Line-Test-for-a-Wireless-Lockbox-1.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="End-of-Line Test for a Wireless Lockbox" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/End-of-Line-Test-for-a-Wireless-Lockbox-1.jpg 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/05/End-of-Line-Test-for-a-Wireless-Lockbox-1-300x107.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/End-of-Line-Test-for-a-Wireless-Lockbox-1-1024x366.jpg 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/05/End-of-Line-Test-for-a-Wireless-Lockbox-1-768x274.jpg 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-3 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/end-of-line-tester-for-a-wireless-lockbox-controller/" target="_self" >End-of-Line Tester for a Wireless Lockbox Controller</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-15146 our_work type-our_work status-publish has-post-thumbnail hentry work_category-automotive work_category-labview work_category-test-measurement-automation">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-156.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-156.png 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-156-300x107.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-156-1024x366.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-156-768x274.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-4 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/functional-end-of-line-test-system-for-automotive-ecus/" target="_self" >Functional End of Line Test System for Automotive ECUs</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-14995 our_work type-our_work status-publish has-post-thumbnail hentry work_category-automotive work_category-labview work_category-test-measurement-automation work_category-test-stand">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-121.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-121.png 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-121-300x107.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-121-1024x366.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-121-768x274.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-5 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/test-stand-automotive-flashing-station/" target="_self" >Test Stand Automotive Flashing Station</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-14681 our_work type-our_work status-publish has-post-thumbnail hentry work_category-data-analysis-data-mining-and-reporting work_category-labview work_category-test-measurement-automation work_category-test-stand">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/8-UP-ECU-Flashing-Station.jpg" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/8-UP-ECU-Flashing-Station.jpg 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/05/8-UP-ECU-Flashing-Station-300x107.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/8-UP-ECU-Flashing-Station-1024x366.jpg 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/05/8-UP-ECU-Flashing-Station-768x274.jpg 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-6 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/8-up-ecu-flashing-station/" target="_self" >8-UP ECU Flashing Station</a></h4>
</li></ul>

</div>
</div>



<div class="wp-block-cb-slide-v2 cb-slide swiper-slide">
<div class="wp-block-query is-layout-flow wp-block-query-is-layout-flow"><ul class="wp-block-post-template is-layout-flow wp-block-post-template-is-layout-flow"><li class="wp-block-post post-15153 our_work type-our_work status-publish has-post-thumbnail hentry work_category-application-development work_category-automotive work_category-pc-application-development">
<figure class="wp-block-post-featured-image"><img decoding="async" width="1400" height="500" src="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-157.png" class="attachment-post-thumbnail size-post-thumbnail wp-post-image" alt="" style="border-radius:20px;object-fit:cover;" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-157.png 1400w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-157-300x107.png 300w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-157-1024x366.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2025/05/unnamed-file-157-768x274.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></figure>

<h4 class="has-link-color wp-elements-7 wp-block-post-title"><a href="https://static.dmcinfo.com/our-work/flexible-desktop-application-for-automotive-chip-flashing/" target="_self" >Flexible Desktop Application for Automotive Chip Flashing</a></h4>
</li></ul>

</div>
</div>
</div></div><div class="cb-pagination swiper-pagination"></div><div class="cb-button-prev swiper-button-prev"></div><div class="cb-button-next swiper-button-next"></div></div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/44756/pcb-test-systems/">Adapting Manufacturing Operations? Flexible PCB and PCBA Testing Is Key to Success </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Zephyr RTOS Explained: Overcoming the Fear of Change</title>
		<link>https://static.dmcinfo.com/blog/44235/zephyr-rtos-explained-overcoming-the-fear-of-change/</link>
		
		<dc:creator><![CDATA[Thomas Panek Gonzalez]]></dc:creator>
		<pubDate>Wed, 06 May 2026 14:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=44235</guid>

					<description><![CDATA[<p>Choose the Right RTOS for Embedded Systems Embedded projects can be very simple and small, with not much going on, but often have a large number of events all looking to happen. To handle all these events, engineers will want to add a Real Time Operating System (RTOS) to their system’s architecture. The purpose of [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/44235/zephyr-rtos-explained-overcoming-the-fear-of-change/">Zephyr RTOS Explained: Overcoming the Fear of Change</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="h-choose-the-right-rtos-for-embedded-systems">Choose the Right RTOS for Embedded Systems</h2>



<p class="wp-block-paragraph">Embedded projects can be very simple and small, with not much going on, but often have a large number of events all looking to happen. To handle all these events, engineers will want to add a Real Time Operating System (RTOS) to their system’s architecture. The purpose of an RTOS is to ensure specific tasks occur within a set time frame. This is very important in embedded devices, as many different tasks must occur for the device to function. </p>



<p class="wp-block-paragraph">Once an RTOS is needed, the next question is which RTOS to use. Some common RTOS options are FreeRTOS, Mbed, ThreadX, and Zephyr. Many have great uses across various systems, though the highlight of this article is Zephyr, as it uses a different methodology for how it works and how it is used. If you&#8217;re reading this article, you may be facing the struggles of Zephyr’s learning curve, but hopefully, by the end, you will gain a greater appreciation for Zephyr.</p>



<h2 class="wp-block-heading" id="h-understanding-zephyr-s-learning-curve">Understanding Zephyr&#8217;s Learning Curve</h2>



<p class="wp-block-paragraph">All things in life need to be learned and dealt with to get the most out of them. Zephyr is the same way, but with a much steeper learning curve for users familiar with other RTOSs. Nearly all users of Zephyr have struggled with it for a reason: the hardware agnosticism, feature set, and continued growth of the RTOS. Most engineers are familiar with how to set up a new project: choose an MCU, define the required features, write drivers, and then test. </p>



<p class="wp-block-paragraph">On Zephyr, the steps are more akin to establishing needed features, writing drivers, and then testing on a long list of possible MCUs. This flip can be hard for many engineers who are familiar with a certain schema, though once one has sipped from the fountain of the future, they may not want to go back. Talk is only so much, though, so now we’ll get into some actual tips and tricks to hopefully help you become a functional Zephyr user!</p>



<h2 class="wp-block-heading" id="h-core-zephyr-concepts-usage-kconfigs-and-device-trees">Core Zephyr Concepts: Usage, Kconfigs, and Device Trees</h2>



<p class="wp-block-paragraph">Zephyr is primarily used via the CLI and a program called “west” to handle nearly everything, including building, flashing, debugging, repo management, and much more. The Zephyr Foundation has <a href="https://docs.zephyrproject.org/latest/develop/getting_started/index.html" target="_blank" rel="noreferrer noopener">documentation</a> on how to install things and is quite helpful for starting out. Once install is done, Zephyr’s greatest hurdles appear on the horizon:</p>



<ol class="wp-block-list">
<li><a href="#h-configuration-files" type="internal" id="#h-configuration-files">Configuration Files</a></li>



<li><a href="#h-device-tree" type="internal" id="#h-device-tree">Device Tree</a></li>



<li><a href="#h-overlay">Overlay</a></li>
</ol>



<p class="wp-block-paragraph">All three are outlined in greater detail below:</p>



<h3 class="wp-block-heading" id="h-configuration-files">Configuration Files</h3>



<p class="wp-block-paragraph">Zephyr is hardware-agnostic, which means the user must say what they want included in the project. There are two files to edit: `kconfig` and `prj.conf`. Kconfig files may be familiar to those who frequent Linux, as Zephyr is a kernel; these are the “kernel configs”. &nbsp;That said, in most cases, not much should need to be changed here, as the stock file created will serve most users just fine. The prj.conf file is the main location where one would define the software’s capabilities, such as the inclusion of logging, UART, ADCs, or SPI. </p>



<p class="wp-block-paragraph">The Zephyr project includes the <a href="https://docs.zephyrproject.org/latest/kconfig.html">full list</a> of variables that can be added to the prj.conf file to configure a project. This is the part that confuses most people, as they either don’t know what to set or would rather set them in the codebase itself, so they feel more like local variables or #defines. This schema enables Zephyr&#8217;s hardware-agnostic nature, since the settings are held outside the driver. To help with the volume of config variables, Zephyr includes a GUI that lets you select settings based on your needs; this helps alleviate the issue of not knowing your options. I wish I had known about this when I was configuring my first project in Zephyr.</p>



<p class="wp-block-paragraph">Zephyr configuration can be done using either a graphical interface or a terminal-based menu, both exposing the same Kconfig options:</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-0e47273b wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-large"><img decoding="async" width="937" height="1024" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-gui-1-937x1024.png" alt="Zephyr GUI" class="wp-image-44260" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-gui-1-937x1024.png 937w, https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-gui-1-275x300.png 275w, https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-gui-1-768x839.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-gui-1.png 959w" sizes="(max-width: 937px) 100vw, 937px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
<figure class="wp-block-image size-full"><img decoding="async" width="955" height="521" src="https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-kernal.png" alt="Zephyr Kernal" class="wp-image-44261" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-kernal.png 955w, https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-kernal-300x164.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/05/zephyr-kernal-768x419.png 768w" sizes="(max-width: 955px) 100vw, 955px" /></figure>
</div>
</div>



<h3 class="wp-block-heading" id="h-device-tree">Device Tree</h3>



<p class="wp-block-paragraph">Where prj.conf files define the software, the device tree defines the hardware. There are three main files in play here:</p>



<ul class="wp-block-list">
<li>.dts. This is an MCU-specific configuration.</li>



<li>.dtsi. It is more general hardware info that can apply to a MCU family or brand of MCUs, potentially</li>
</ul>



<h3 class="wp-block-heading" id="h-overlay">.Overlay</h3>



<p class="wp-block-paragraph">While the first two are often left alone as is, since they define the capabilities of the MCU, which don’t change. User intervention is needed within the .overlay file. This is where the peripherals are set up, along with the pins used to control them. An example of the overlay structure can be found <a href="https://docs.zephyrproject.org/latest/build/dts/howtos.html#use-devicetree-overlays" target="_blank" rel="noreferrer noopener">here at the bottom of the section</a>; the example shown is for an SPI and I2C setup. The .overlay will need to be curated for each hardware-related function of the setup. These created peripherals will later be used in the main code.</p>



<h2 class="wp-block-heading" id="h-moving-forward-with-zephyr">Moving Forward with Zephyr</h2>



<p class="wp-block-paragraph">In my experience and others’ sentiments, the ability to grasp the purpose and schema of the files above is the biggest hurdle in Zephyr. Once those are understood, the rest of Zephyr is quite similar to other RTOS or general embedded methodologies. It’s highly recommended to follow a guide when setting up a sample project before starting your own, as guidance can be very beneficial when starting out with Zephyr.</p>



<h3 class="wp-block-heading" id="h-practical-considerations">Practical Considerations</h3>



<p class="wp-block-paragraph">Currently, it is hard to avoid AI. For a case like Zephyr, it can be quite useful for understanding what to add to one’s prj.conf and .overlay files. Be aware that these config variables may change over time, and new ones may be unfamiliar to the AI model. It&#8217;s best to consult official sources if things are not working/building correctly.</p>



<h3 class="wp-block-heading" id="h-additional-resources">Additional Resources</h3>



<p class="wp-block-paragraph">Here are a few reference materials to help get you on the right path in your Zephyr journey:</p>



<ul class="wp-block-list">
<li><a href="https://docs.zephyrproject.org/latest/index.html" type="link" id="https://docs.zephyrproject.org/latest/index.html">Zephyr Project Home</a></li>



<li><a href="https://gateway.on24.com/wcc/eh/2295376/category/144246/mastering-zephyr-rtos" type="link" id="https://gateway.on24.com/wcc/eh/2295376/category/144246/mastering-zephyr-rtos">Mastering Zephyr Webinar</a></li>
</ul>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step">Have an upcoming project? DMC can help you take the next step.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Take your project to the next level with engineering solutions from DMC. Learn more about our <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" id="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/">Embedded Development &amp; Programming</a> solutions or contact us to get started today!</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/44235/zephyr-rtos-explained-overcoming-the-fear-of-change/">Zephyr RTOS Explained: Overcoming the Fear of Change</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Power Profiling Embedded Systems: Tools, Techniques, and Real-World Results</title>
		<link>https://static.dmcinfo.com/blog/42943/power-profiling-embedded-systems/</link>
		
		<dc:creator><![CDATA[Thomas Panek Gonzalez]]></dc:creator>
		<pubDate>Tue, 14 Apr 2026 19:53:37 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<category><![CDATA[Low-Power Embedded Design]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=42943</guid>

					<description><![CDATA[<p>Batteries have brought us into a cordless era, from electric vehicles with 75KWh batteries to handheld devices powered by 0.66Wh coin cells. Regardless of the use case (hand warmers aside), the customer wants the most efficient system, thus the longest battery life. To improve battery life, designers need to understand where power is being consumed [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/42943/power-profiling-embedded-systems/">Power Profiling Embedded Systems: Tools, Techniques, and Real-World Results</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Batteries have brought us into a cordless era, from <a href="https://static.dmcinfo.com/industries/automotive/">electric vehicles with 75KWh batteries</a> to <a href="https://static.dmcinfo.com/our-work/category/industry/consumer-goods/">handheld devices</a> powered by 0.66Wh coin cells. Regardless of the use case (hand warmers aside), the customer wants the most efficient system, thus the longest battery life. To improve battery life, designers need to understand where power is being consumed so they can reduce it. One of the best ways to do that is to measure current over time with a power profiler.</p>



<h2 id="h-what-is-a-power-profiler" class="wp-block-heading">What Is a Power Profiler?</h2>



<p class="wp-block-paragraph">A power profiler precisely measures the power a device consumes over a given period of time. Often, a graph is generated with the data so one can examine consistency and anomalies. Typically, the power profiler supplies power to the device, so all power flows through the profiler, enabling better measurement. In contrast, one would need to place a digital multimeter (DMM) in line with the device to measure current, and have the voltage measured with a separate instrument. An engineer would then use this data to observe how changes in hardware and software are affecting the device’s power consumption.</p>



<h2 id="h-devices-used" class="wp-block-heading">Devices Used</h2>



<p class="wp-block-paragraph">We typically use two main power profilers when working on low-power Embedded systems:</p>



<ul class="wp-block-list">
<li><a href="https://www.nordicsemi.com/Products/Development-hardware/Power-Profiler-Kit-2" target="_blank" rel="noreferrer noopener">Nordic Power Profiler Kit II</a>. It is usually referred to as PPK2 (Power Profiler Kit 2) and is a USB device that plugs into a computer and uses Nordic’s software to view the power characteristics of the device in question.</li>



<li><a href="https://www.qoitech.com/otii-ace/" target="_blank" rel="noreferrer noopener">Qoitech Otii Ace Pro</a>. The Otii does the same thing as the PPK2, though with a more comprehensive feature set. It offers a wider range of voltage and current, better read resolutions, and other features. It is worth noting that this tool is more expensive.</li>
</ul>



<h2 id="h-lower-power-techniques" class="wp-block-heading">Lower Power Techniques</h2>



<p class="wp-block-paragraph">It is one thing to know a device&#8217;s power draw; it&#8217;s another to know how to lower its average draw. In the simplest terms, the best way to reduce power draw is to turn off as many things as possible. LEDs, Integrated Circuits (ICs), and the microcontroller (MCU) can all be powered on, off, or put to sleep via smart decisions made in hardware and software. Adding a Metal-Oxide-Semiconductor Field-Effect Transistor (MOSFET) or specialized power switches allows subsystems to be turned on and off as needed. Most MCUs support various sleep modes, which can reduce average power by orders of magnitude.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">As an example, the ESP32, a popular MCU, provides a table in its datasheet that shows various sleep modes and their power consumption in those modes. Looking at these tables (see Figures 1 and 2 below), it&#8217;s seen that a maximum of 240 mA can be reduced to 5 µA by changing the power mode, a ~48,000-fold difference.</p>



<figure class="wp-block-image aligncenter size-full" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--50)"><img decoding="async" width="624" height="250" src="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-1.png" alt="Power modes and consumption for ESP32." class="wp-image-42944" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-1.png 624w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-1-300x120.png 300w" sizes="(max-width: 624px) 100vw, 624px" /><figcaption class="wp-element-caption"><em>Figure 1: Power modes and consumption for ESP32</em></figcaption></figure>



<figure class="wp-block-image aligncenter size-full" style="margin-top:var(--wp--preset--spacing--30);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="624" height="187" src="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-2.png" alt="Active RF power consumption." class="wp-image-42945" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-2.png 624w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-2-300x90.png 300w" sizes="(max-width: 624px) 100vw, 624px" /><figcaption class="wp-element-caption"><em>Figure 2: Active RF power consumption</em></figcaption></figure>



<h2 id="h-examples" class="wp-block-heading">Examples</h2>



<p class="wp-block-paragraph">Out of simplicity, I will provide some data and examples using the Arduino Nano R4. This is Arduino’s smallest microcontroller development kit board and can be used for simple projects, including low-power applications. I’ll recreate the same setup in two different ways, both of which will result in a simple blinky program.</p>



<p class="wp-block-paragraph">For hardware, a Nano R4 will be plugged into a breadboard along with an LED and a resistor. The LED will blink at 2Hz in both software setups, though the second will include power-saving logic. Figures 3 and 4 below show a large drop in power when the CPU is put to sleep with nothing happening. In normal operation, the MCU idles and consumes power doing nothing, whereas in the sleep code, it can sleep and consume much less power.</p>



<p class="wp-block-paragraph">Figure 3 shows an average power draw of 24.3 mA in the 20s window, while the low-power version shown in Figure 4 has an average draw of 13.4 mA, nearly half the current used. These numbers can mean very little without some context. If the system were powered by a single CR2032 3V coin cell battery with a capacity of 225 mAh, the runtime would range from 225 mAh / 24.3 mA = 9.25 h to 16.8 h.</p>



<p class="wp-block-paragraph">This is roughly double the runtime under ideal situations. The true benefits of low power come from using a device with ultra-low-power saving modes, as seen in Figure 1 for the ESP32. If the same rough calculations are done with the modem off vs hibernation, we see a runtime range of 225mAh/25mA = 9hours to 225mAh/5uA =45000h = 1875days = 5.13years.</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--40)">This is a perfect-world situation and is highly unlikely to happen, especially as it assumes the device would be asleep for the entire time, doing nothing productive. Though systems can be optimized to last for months or years, depending on their use case and the amount of power-saving logic applied.</p>



<figure class="wp-block-image aligncenter size-full" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="925" height="519" src="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-3-2.jpg" alt="Average power draw of 24.3 mA in the 20s window." class="wp-image-42974" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-3-2.jpg 925w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-3-2-300x168.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-3-2-768x431.jpg 768w" sizes="(max-width: 925px) 100vw, 925px" /><figcaption class="wp-element-caption"><em>Figure 3: Simple Blinky</em></figcaption></figure>



<figure class="wp-block-image aligncenter size-full" style="margin-top:var(--wp--preset--spacing--40);margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="925" height="520" src="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-4.jpg" alt="Low-power version, average draw of 13.4 mA." class="wp-image-42976" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-4.jpg 925w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-4-300x169.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2026/04/hardware-embedded-devices-power-profiling-figure-4-768x432.jpg 768w" sizes="(max-width: 925px) 100vw, 925px" /><figcaption class="wp-element-caption"><em>Figure 4: Low Power Blinky</em></figcaption></figure>



<h2 id="h-code" class="wp-block-heading">Code</h2>



<p class="wp-block-paragraph">Below are the two sketches used for the measurements above:</p>



<ul class="wp-block-list">
<li>A baseline 2 Hz blinky</li>



<li style="padding-bottom:var(--wp--preset--spacing--50)">A low-power version that uses <strong>__WFI()</strong> to sleep between timer ticks</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>//Baseline 2Hz Blinky
const int LED_PIN = 3;      // Built-in LED on Arduino Nano
const unsigned long TOGGLE_MS = 250;

unsigned long lastToggle = 0;
bool ledState = false;

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  unsigned long now = millis();

  if (now - lastToggle >= TOGGLE_MS) {
    lastToggle = now;
    ledState = !ledState;
    digitalWrite(LED_PIN, ledState);
  }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">//Baseline 2Hz Blinky</span></span>
<span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">int</span><span style="color: #D4D4D4"> LED_PIN = </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">;      </span><span style="color: #6A9955">// Built-in LED on Arduino Nano</span></span>
<span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">unsigned</span><span style="color: #D4D4D4"> long TOGGLE_MS = </span><span style="color: #B5CEA8">250</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #9CDCFE">unsigned</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">long</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">lastToggle</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #9CDCFE">bool</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ledState</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setup</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">pinMode</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">OUTPUT</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">loop</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">unsigned</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">long</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">now</span><span style="color: #D4D4D4"> = </span><span style="color: #DCDCAA">millis</span><span style="color: #D4D4D4">();</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">now</span><span style="color: #D4D4D4"> - </span><span style="color: #9CDCFE">lastToggle</span><span style="color: #D4D4D4"> &gt;= </span><span style="color: #4FC1FF">TOGGLE_MS</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">lastToggle</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">now</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">ledState</span><span style="color: #D4D4D4"> = !</span><span style="color: #9CDCFE">ledState</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">digitalWrite</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">ledState</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">JavaScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>// Low Power 2Hz Blinky
#include &lt;Arduino.h>
const uint8_t LED_PIN = 3;
volatile bool tick = false;
extern "C" void SysTick_Handler(void)
{
  tick = true;
}

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);

  // Configure SysTick for 250 ms ticks
  SysTick_Config(SystemCoreClock / 4);  // 1/4 second = 250 ms
}

void loop()
{
  // Wait in low-power idle until interrupt fires
  while (!tick) {
    __WFI();   // Wait For Interrupt (CPU sleeps until an interrupt occurs)
  }
  tick = false;

  // Toggle LED each tick
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955">// Low Power 2Hz Blinky</span></span>
<span class="line"><span style="color: #D4D4D4">#</span><span style="color: #9CDCFE">include</span><span style="color: #D4D4D4"> &lt;</span><span style="color: #9CDCFE">Arduino</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">h</span><span style="color: #D4D4D4">&gt;</span></span>
<span class="line"><span style="color: #569CD6">const</span><span style="color: #D4D4D4"> </span><span style="color: #4FC1FF">uint8_t</span><span style="color: #D4D4D4"> LED_PIN = </span><span style="color: #B5CEA8">3</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #9CDCFE">volatile</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">bool</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">tick</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #9CDCFE">extern</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;C&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">SysTick_Handler</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">void</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">tick</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setup</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">pinMode</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">OUTPUT</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">digitalWrite</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">, </span><span style="color: #4FC1FF">LOW</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">// Configure SysTick for 250 ms ticks</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">SysTick_Config</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">SystemCoreClock</span><span style="color: #D4D4D4"> / </span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">);  </span><span style="color: #6A9955">// 1/4 second = 250 ms</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">loop</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">// Wait in low-power idle until interrupt fires</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> (!</span><span style="color: #9CDCFE">tick</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">__WFI</span><span style="color: #D4D4D4">();   </span><span style="color: #6A9955">// Wait For Interrupt (CPU sleeps until an interrupt occurs)</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">tick</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #6A9955">// Toggle LED each tick</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">digitalWrite</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">, !</span><span style="color: #DCDCAA">digitalRead</span><span style="color: #D4D4D4">(</span><span style="color: #4FC1FF">LED_PIN</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 id="h-conclusion" class="wp-block-heading" style="padding-top:var(--wp--preset--spacing--50)">Conclusion</h2>



<p class="wp-block-paragraph">Power profiling turns battery life from a guessing game into a measurable target for engineers. By capturing current over time, you can quickly spot spikes, reduce idle waste, and validate that firmware and hardware changes actually improve energy use. Even small changes, like sleeping between periodic tasks, can meaningfully reduce average current, and deeper optimizations can extend runtime further.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Want to optimize the power consumption of your embedded device?</strong> Ask DMC.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Power profiling can improve the battery life of your embedded project. Learn more about DMC&#8217;s <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">embedded</a> expertise and our <a href="https://static.dmcinfo.com/services/test-and-measurement-automation/battery-pack-and-bms-test-systems/" data-type="page" data-id="611">battery life</a> optimization capabilities</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/42943/power-profiling-embedded-systems/">Power Profiling Embedded Systems: Tools, Techniques, and Real-World Results</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Battery Life Calculator</title>
		<link>https://static.dmcinfo.com/blog/41922/battery-life-calculator/</link>
		
		<dc:creator><![CDATA[Tim Jager]]></dc:creator>
		<pubDate>Thu, 05 Mar 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<category><![CDATA[Low-Power Embedded Design]]></category>
		<category><![CDATA[Product Development]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=41922</guid>

					<description><![CDATA[<p>As engineers who design electronic products, maximizing battery life is a constant challenge. Devices keep getting smaller while their feature sets continue to grow, forcing us to carefully manage power consumption across multiple operating modes, batteries, and power conversion stages. This calculator helps explore those tradeoffs by letting you tune system parameters and compare different [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/41922/battery-life-calculator/">Battery Life Calculator</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As engineers who design electronic products, maximizing battery life is a constant challenge. Devices keep getting smaller while their feature sets continue to grow, forcing us to carefully manage power consumption across multiple operating modes, batteries, and power conversion stages.</p>



<p class="wp-block-paragraph">This calculator helps explore those tradeoffs by letting you tune system parameters and compare different battery and power architecture options. Unlike many simple online calculators, it breaks power usage down by operating mode and accounts for conversion efficiency so you can better see where energy is going and how design choices affect battery life.</p>



<style>
    /* Root layout */
    .dmc-calc-root {
      margin: 2rem auto;
      padding: 1.5rem;
      border: 1px solid #ccc;
      border-radius: 8px;
      background-color: #fff;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    }

    .dmc-calc-root h1 {
      margin-top: 0;
      margin-bottom: 0.25rem;
      font-size: 1.6rem;
    }

    .dmc-calc-root p.dmc-calc-subtitle {
      margin-top: 0;
      color: #555;
      font-size: 0.95rem;
    }

    .dmc-calc-section {
      margin-top: 1.75rem;
    }

    .dmc-calc-section h2 {
      margin: 0 0 0.75rem 0;
      font-size: 1.25rem;
      border-bottom: 1px solid #ddd;
      padding-bottom: 0.25rem;
    }

    .dmc-calc-section h3 {
      margin: 1rem 0 0.5rem 0;
      font-size: 1.05rem;
    }

    /* Battery configuration */
    .dmc-calc-battery-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
      gap: 0.75rem 1rem;
    }

    .dmc-calc-field {
      display: flex;
      flex-direction: column;
      font-size: 0.9rem;
    }

    .dmc-calc-field label {
      margin-bottom: 0.15rem;
      font-weight: 600;
    }

    .dmc-calc-field input,
    .dmc-calc-field select {
      padding: 0.3rem 0.4rem;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 0.9rem;
    }

    .dmc-calc-field input.dmc-calc-readonly {
      background-color: #f4f6fb;
      border-color: #cdd6e4;
      color: #394255;
      cursor: not-allowed;
    }

    .dmc-calc-field input.dmc-calc-readonly:focus {
      outline: none;
      box-shadow: none;
    }

    .dmc-calc-field span.dmc-calc-unit {
      font-size: 0.8rem;
      color: #666;
      margin-top: 0.15rem;
    }

    .dmc-calc-example-links {
      margin: 0;
      padding-left: 1.05rem;
      display: flex;
      flex-direction: column;
      gap: 0.35rem;
    }

    .dmc-calc-example-links li {
      line-height: 1.3;
    }

    .dmc-calc-example-links a {
      color: #0057b8;
      text-decoration: underline;
      text-underline-offset: 2px;
    }

    .dmc-calc-example-links a:hover,
    .dmc-calc-example-links a:focus-visible {
      color: #003f84;
    }

    .dmc-calc-example-blurb {
      margin: 0.1rem 0 0 0;
      color: #666;
      font-size: 0.78rem;
    }

    /* Rails and modes tables */
    .dmc-calc-table-wrapper {
      overflow-x: auto;
    }

    .dmc-calc-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 0.85rem;
      min-width: 760px;
    }

    .dmc-calc-table th,
    .dmc-calc-table td {
      border: 1px solid #ddd;
      padding: 0.3rem;
      text-align: left;
      vertical-align: middle;
      white-space: nowrap;
    }

    .dmc-calc-table thead {
      background-color: #f7f7f7;
      position: sticky;
      top: 0;
      z-index: 1;
    }

    .dmc-calc-table th {
      font-weight: 600;
    }

    .dmc-calc-table input,
    .dmc-calc-table select {
      width: 100%;
      box-sizing: border-box;
      font-size: 0.8rem;
      padding: 0.2rem 0.25rem;
    }

    .dmc-calc-rails-table input[data-rail-field="name"] {
      max-width: 6rem;
    }

    .dmc-calc-rails-table input[data-rail-field="voltage"] {
      max-width: 4.75rem;
    }

    .dmc-calc-rails-table input[data-rail-field="efficiency"],
    .dmc-calc-rails-table input[data-rail-field="eff-low-pct"],
    .dmc-calc-rails-table input[data-rail-field="eff-high-pct"] {
      max-width: 3.5rem;
    }

    .dmc-calc-rails-table input[data-rail-field="iq-ua"] {
      max-width: 6rem;
    }

    .dmc-calc-rails-table select[data-rail-field="parent"] {
      max-width: 8rem;
    }

    .dmc-calc-rails-eff-mode-hidden:disabled {
      color: transparent;
      text-shadow: none;
      -webkit-text-fill-color: transparent;
    }

    .dmc-calc-rails-table {
      min-width: 640px;
    }

    .dmc-calc-loads-table {
      min-width: 640px;
    }

    .dmc-calc-modes-table {
      min-width: 1000px;
    }

    .dmc-calc-modes-table input[data-load-id] {
      width: 4.5rem;
      min-width: 4.5rem;
      max-width: 4.5rem;
    }

    .dmc-calc-modes-table input[data-mode-field="period"] {
      width: 4.5rem;
      min-width: 4.5rem;
    }

    .dmc-calc-input-with-unit {
      display: inline-flex;
      align-items: center;
      gap: 0.15rem;
    }

    .dmc-calc-input-with-unit > input,
    .dmc-calc-input-with-unit > .dmc-calc-computed-field {
      box-sizing: border-box;
      height: 1.95rem;
      line-height: 1.2;
    }

    .dmc-calc-input-with-unit select {
      width: auto;
      min-width: 4.9rem;
      padding: 0.2rem 0.2rem;
      padding-right: 1.45rem;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 0.85rem;
      color: #111;
      background-color: #fff;
      flex: 0 0 auto;
      -webkit-appearance: menulist;
      appearance: auto;
    }

    .dmc-calc-unit-label {
      width: 4.9rem;
      min-width: 4.9rem;
      box-sizing: border-box;
      height: 1.95rem;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      padding: 0.2rem 0.2rem;
      border: 1px solid #ccc;
      border-radius: 4px;
      background-color: #f7f7f7;
      color: #394255;
      font-size: 0.85rem;
      font-weight: 600;
      user-select: none;
    }

    .dmc-calc-modes-table input[data-mode-field="name"] {
      width: 9rem;
      min-width: 9rem;
    }

    .dmc-calc-computed-field {
      display: inline-block;
      padding: 0.3rem 0.4rem;
      background-color: #f4f6fb;
      border: 1px solid #cdd6e4;
      border-radius: 4px;
      font-size: 0.9rem;
      color: #394255;
      font-variant-numeric: tabular-nums;
      text-align: right;
      min-width: 4.5rem;
    }

    .dmc-calc-modes-table .dmc-calc-mode-period-value {
      width: 4.5rem;
      min-width: 4.5rem;
    }

    .dmc-calc-modes-table .dmc-calc-mode-active-value {
      width: 5.5rem;
      min-width: 5.5rem;
    }

    .dmc-calc-modes-table input[data-mode-field="active"] {
      width: 5.5rem;
      min-width: 5.5rem;
    }

    .dmc-calc-modes-table .dmc-blc-duty,
    .dmc-calc-modes-table .dmc-blc-avg-power,
    .dmc-calc-modes-table .dmc-blc-contrib {
      font-variant-numeric: tabular-nums;
      text-align: right;
      display: inline-block;
      min-width: 2.2rem;
    }

    .dmc-calc-modes-table th.dmc-calc-narrow-col,
    .dmc-calc-modes-table td.dmc-calc-narrow-col {
      width: 3.2rem;
      min-width: 3.2rem;
      max-width: 3.5rem;
      white-space: normal;
      line-height: 1.3;
      text-align: right;
    }

    .dmc-calc-modes-table td[role="button"] {
      padding: 0.3rem 0.15rem;
      width: 2rem;
      min-width: 2rem;
    }

    .dmc-calc-modes-table .dmc-calc-delete-col {
      width: 2rem;
      min-width: 2rem;
      padding: 0.3rem 0.15rem;
      text-align: center;
    }

    .dmc-calc-rails-eff-cell {
      white-space: normal;
    }

    .dmc-calc-rails-eff-cell input[data-rail-field="efficiency"],
    .dmc-calc-rails-eff-cell {
      white-space: normal;
    }

    .dmc-calc-rails-eff-rows {
      display: grid;
      gap: 0.2rem;
      align-items: center;
    }

    .dmc-calc-rails-eff-row {
      display: grid;
      grid-template-columns: auto 3.25rem auto 4rem auto;
      align-items: center;
      gap: 0.2rem;
    }

    .dmc-calc-rails-eff-row input[type="number"] {
      width: 100%;
      min-width: 3rem;
    }

    .dmc-calc-rails-eff-row span {
      color: #555;
      font-size: 0.85rem;
      white-space: nowrap;
    }

    .dmc-calc-rails-eff-label {
      display: inline-block;
      min-width: 2.6rem;
      text-align: right;
    }

    .dmc-calc-rails-eff-rows .dmc-calc-rails-eff-simple-only {
      grid-template-columns: 1fr;
      gap: 0;
    }

    /* Topology diagram */
    .dmc-calc-topology {
      margin: 1rem 0 1.25rem 0;
      padding: 0.75rem;
      border: 1px solid #e0e0e0;
      border-radius: 6px;
      background: linear-gradient(120deg, #fafafa 0%, #f5f7fa 100%);
    }

    .dmc-calc-topology {
      position: relative;
    }

    .dmc-calc-topology svg {
      width: 100%;
      height: 100%;
      min-height: 360px;
      max-height: 600px;
      display: block;
    }

    .dmc-calc-modes-actions {
      margin-top: 0.5rem;
      display: flex;
      gap: 0.5rem;
    }

    /* Concept tiles */
    .dmc-calc-concepts-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
      gap: 0.9rem;
      margin-top: 0.75rem;
    }

    .dmc-calc-concept-card {
      border: 1px solid #e0e0e0;
      border-radius: 6px;
      padding: 0.6rem 0.75rem;
      background: #fcfcff;
    }

    .dmc-calc-concept-name {
      font-weight: 600;
      margin: 0 0 0.35rem 0;
    }

    .dmc-calc-concept-detail {
      margin: 0.15rem 0;
      font-size: 0.86rem;
    }

    .dmc-calc-concept-detail em {
      font-style: normal;
      font-weight: 600;
      display: block;
      margin-bottom: 0.05rem;
    }

    .dmc-calc-2pt-demo {
      margin-top: 0.5rem;
      padding: 0.45rem 0.55rem;
      border: 1px solid #d8dee8;
      border-radius: 6px;
      background: #ffffff;
    }

    .dmc-calc-2pt-demo svg {
      display: block;
      width: 100%;
      height: 122px;
    }

    .dmc-calc-2pt-rules {
      margin: 0.4rem 0 0 0.95rem;
      padding: 0;
      color: #4a4a4a;
      font-size: 0.79rem;
      line-height: 1.35;
    }

    /* Results cards */
    .dmc-calc-results-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
      gap: 0.75rem;
    }

    .dmc-calc-card {
      border: 1px solid #ddd;
      border-radius: 6px;
      padding: 0.75rem 0.9rem;
      background-color: #fafafa;
    }

    .dmc-calc-card h3 {
      margin: 0 0 0.3rem 0;
      font-size: 0.95rem;
    }

    .dmc-calc-card-value {
      font-size: 1.1rem;
      font-weight: 600;
      margin-bottom: 0.15rem;
    }

    .dmc-calc-card-sub {
      font-size: 0.8rem;
      color: #666;
    }

    /* Mode contribution bars */
    .dmc-calc-mode-bars {
      margin-top: 1rem;
      font-size: 0.85rem;
    }

    .dmc-calc-mode-bars h3 {
      margin: 0 0 0.5rem 0;
      font-size: 0.95rem;
    }

    .dmc-calc-mode-bars-body {
      display: flex;
      flex-direction: column;
      gap: 0.35rem;
    }

    .dmc-calc-mode-bar-row {
      display: grid;
      grid-template-columns: minmax(100px, 140px) 1fr minmax(56px, 68px);
      align-items: center;
      gap: 0.5rem;
    }

    .dmc-calc-mode-bar-label {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    .dmc-calc-mode-bar-track {
      position: relative;
      height: 10px;
      border-radius: 999px;
      background-color: #eee;
      overflow: hidden;
    }

    .dmc-calc-mode-bar {
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      border-radius: 999px;
      background-color: #0074d9;
    }

    .dmc-calc-mode-bar-value {
      text-align: right;
      font-variant-numeric: tabular-nums;
      color: #444;
    }

    /* Sticky summary banner */
    #dmc-blc-summary-banner-container {
      display: flex;
      justify-content: flex-end;
      margin-bottom: 20px;
      position: sticky;
      top: 170px;
	  z-index: 60;
    }
    .dmc-calc-summary-banner {
      width: calc(100% - 1.4rem);
      margin: 0;
      padding: 0.45rem 0.7rem 0.55rem 0.7rem;
      border: 2px solid #0b5fc6;
      border-radius: 12px;
      background: linear-gradient(180deg, #f7fbff 0%, #edf4ff 100%);
      box-shadow: 0 8px 18px rgba(11, 95, 198, 0.18);
      display: flex;
      flex-direction: column;
      gap: 0.35rem 0.6rem;
      align-items: stretch;
      transition: transform 220ms ease, box-shadow 220ms ease;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-down {
      transform: translate(0, -8px);
      box-shadow: 0 4px 10px rgba(11, 95, 198, 0.14);
    }

    .dmc-calc-summary-banner-head {
      display: flex;
      align-items: center;
      gap: 0.5rem;
    }

    .dmc-calc-summary-banner-title {
      flex: 1 1 auto;
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      color: #0b4a92;
      margin: 0;
      line-height: 1.15;
    }

    .dmc-calc-summary-toggle {
      flex: 0 0 auto;
      border: 1px solid #8fb3e0;
      border-radius: 999px;
      background: #ffffff;
      color: #225392;
      font-size: 0.72rem;
      font-weight: 700;
      letter-spacing: 0.02em;
      padding: 0.18rem 0.55rem;
      cursor: pointer;
      line-height: 1.2;
    }

    .dmc-calc-summary-toggle:hover,
    .dmc-calc-summary-toggle:focus-visible {
      border-color: #0b5fc6;
      color: #0b4a92;
      outline: none;
    }

    .dmc-calc-summary-banner-content {
      display: grid;
      grid-template-columns: repeat(3, minmax(220px, 1fr));
      gap: 0.35rem 0.6rem;
      align-items: center;
    }

    .dmc-calc-summary-pill {
      display: flex;
      flex-direction: column;
      gap: 0.08rem;
      background-color: #ffffff;
      border: 1px solid #d5deec;
      border-radius: 9px;
      padding: 0.28rem 0.45rem;
    }

    .dmc-calc-summary-pill-label {
      font-size: 0.74rem;
      color: #4f5f78;
      font-weight: 600;
    }

    .dmc-calc-summary-pill-value {
      font-size: 0.98rem;
      font-weight: 700;
      font-variant-numeric: tabular-nums;
      color: #1f2c42;
    }

    .dmc-calc-summary-pill-primary {
      border: 2px solid #ea8a15;
      background: linear-gradient(180deg, #fff9ef 0%, #fff2dc 100%);
      box-shadow: 0 2px 8px rgba(234, 138, 21, 0.18);
    }

    .dmc-calc-summary-pill-primary .dmc-calc-summary-pill-label {
      color: #8b4b00;
    }

    .dmc-calc-summary-pill-primary .dmc-calc-summary-pill-value {
      font-size: clamp(1.08rem, 2vw, 1.3rem);
      line-height: 1.1;
      color: #7a2e00;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed {
      transform: translate(0, 0);
      width: max-content;
      max-width: calc(100vw - 1.3rem);
      padding: 0.2rem 0.28rem;
      gap: 0.16rem;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-banner-title {
      display: none;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-banner-content {
      grid-template-columns: 1fr;
      gap: 0.25rem;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-pill-secondary {
      display: none;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-pill-primary {
      border-width: 1px;
      box-shadow: none;
      padding: 0.12rem 0.34rem;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-pill-primary .dmc-calc-summary-pill-label {
      display: none;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-pill-primary .dmc-calc-summary-pill-value {
      font-size: 0.86rem;
      color: #4f2b00;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed .dmc-calc-summary-toggle {
      font-size: 0.68rem;
      padding: 0.1rem 0.42rem;
    }

    .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed.dmc-calc-summary-banner-down {
      transform: translate(0, -8px);
    }

    /* Share section */
    .dmc-calc-share-row {
      display: flex;
      flex-wrap: wrap;
      gap: 0.5rem;
      align-items: center;
    }

    .dmc-calc-share-row button {
      white-space: nowrap;
    }

    .dmc-calc-share-row input[type="text"] {
      flex: 1 1 220px;
      min-width: 0;
      padding: 0.3rem 0.4rem;
      border: 1px solid #ccc;
      border-radius: 4px;
      font-size: 0.85rem;
    }

    .dmc-calc-share-status {
      font-size: 0.8rem;
      color: #555;
      margin-top: 0.3rem;
    }

    /* Buttons */
    .dmc-calc-button {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border-radius: 4px;
      border: 1px solid #0074d9;
      background-color: #0074d9;
      color: #fff;
      padding: 0.35rem 0.7rem;
      font-size: 0.85rem;
      cursor: pointer;
    }

    .dmc-calc-button.dmc-calc-secondary {
      background-color: #f5f5f5;
      border-color: #ccc;
      color: #333;
    }

    .dmc-calc-button:disabled {
      opacity: 0.6;
      cursor: default;
    }

    /* Explanation details */
    .dmc-calc-explainer {
      font-size: 0.9rem;
    }

    .dmc-calc-explainer summary {
      cursor: pointer;
      font-weight: 600;
    }

    .dmc-calc-explainer p {
      margin-top: 0.4rem;
      margin-bottom: 0.4rem;
    }

    /* Small helpers */
    .dmc-calc-muted {
      color: #666;
      font-size: 0.8rem;
    }

    .dmc-calc-warning {
      color: #a33;
      font-size: 0.85rem;
      margin-top: 0.45rem;
    }

    .dmc-calc-align-right {
      text-align: right;
    }

    .dmc-calc-collapsible {
      border: 1px solid #e0e0e0;
      border-radius: 6px;
      padding: 0.4rem 0.75rem 0.75rem 0.75rem;
      background: linear-gradient(180deg, #fafafa 0%, #fdfdfd 100%);
    }

    .dmc-calc-collapsible summary {
      cursor: pointer;
      list-style: none;
    }

    .dmc-calc-collapsible summary::-webkit-details-marker {
      display: none;
    }

    .dmc-calc-collapsible summary h2 {
      display: inline-block;
      margin: 0 0 0.35rem 0;
    }

    .dmc-calc-chem-curve {
      margin-top: 1.25rem;
      padding: 1rem;
      border: 1px solid #ddd;
      border-radius: 8px;
      background: linear-gradient(180deg, #fcfcfc 0%, #f5f6fa 100%);
    }

    .dmc-calc-chem-curve-header {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      align-items: flex-end;
      gap: 0.5rem;
    }

    .dmc-calc-chem-curve-header h3 {
      margin: 0;
      font-size: 1.05rem;
    }

    .dmc-calc-chem-curve canvas {
      display: block;
      width: 100%;
      height: 260px;
      min-height: 220px;
      margin-top: 0.75rem;
      border-radius: 4px;
      background-color: #fff;
      box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.04);
    }

    .dmc-calc-chem-curve-legend {
      display: flex;
      flex-wrap: wrap;
      gap: 0.75rem;
      font-size: 0.85rem;
      color: #444;
    }

    .dmc-calc-chem-curve-note {
      margin-top: 0.4rem;
      font-size: 0.8rem;
      color: #666;
    }

    .dmc-calc-chem-curve-stats {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
      gap: 0.5rem 1rem;
      margin-top: 0.75rem;
      font-size: 0.85rem;
      color: #333;
    }

    .dmc-calc-chem-curve-stat-label {
      display: block;
      color: #666;
      font-size: 0.78rem;
      margin-bottom: 0.15rem;
    }

    .dmc-calc-chem-curve-stat-value {
      font-variant-numeric: tabular-nums;
    }

    @media (max-width: 640px) {
      .dmc-calc-root {
        margin: 1rem;
        padding: 1rem;
      }

      #dmc-blc-summary-banner-container {
        top: 90px;
      }

      .dmc-calc-summary-banner {
        width: calc(100% - 1.1rem);
        right: auto;
        bottom: auto;
        padding: 0.45rem 0.55rem 0.5rem 0.55rem;
        grid-template-columns: 1fr;
      }

      .dmc-calc-summary-banner-content {
        grid-template-columns: 1fr;
      }

      .dmc-calc-summary-banner-title {
        font-size: 0.68rem;
      }
      .dmc-calc-summary-banner.dmc-calc-summary-banner-collapsed {
        max-width: calc(100vw - 1rem);
      }
    }
.dmc-calc-section p code {
	padding: inherit;
	background-color: inherit;
	border-radius: inherit !important;
	color: inherit;
	font-size: inherit;
	box-decoration-break: inherit;
	-webkit-box-decoration-break: inherit;
}
  </style>
</head>
<body>
  <div id="battery-life-calculator" class="dmc-calc-root">
    <div id="dmc-blc-summary-banner-container">
      <div id="dmc-blc-summary-banner" class="dmc-calc-summary-banner" aria-label="Key results summary" data-collapsed="false">
        <div class="dmc-calc-summary-banner-head">
          <div class="dmc-calc-summary-banner-title">Final battery life estimate</div>
          <button type="button" id="dmc-blc-summary-toggle" class="dmc-calc-summary-toggle" aria-expanded="true" aria-controls="dmc-blc-summary-content">Collapse</button>
        </div>
        <div id="dmc-blc-summary-content" class="dmc-calc-summary-banner-content">
          <div class="dmc-calc-summary-pill dmc-calc-summary-pill-secondary">
            <span class="dmc-calc-summary-pill-label">Average power</span>
            <span class="dmc-calc-summary-pill-value" id="dmc-blc-summary-avg">&#8212; uW</span>
          </div>
          <div class="dmc-calc-summary-pill dmc-calc-summary-pill-secondary">
            <span class="dmc-calc-summary-pill-label">Usable pack energy</span>
            <span class="dmc-calc-summary-pill-value" id="dmc-blc-summary-energy">&#8212;</span>
          </div>
          <div class="dmc-calc-summary-pill dmc-calc-summary-pill-primary">
            <span class="dmc-calc-summary-pill-label">Life</span>
            <span class="dmc-calc-summary-pill-value" id="dmc-blc-summary-life">&#8212;</span>
          </div>
        </div>
      </div>
      </div>
    <header>
      <h2>Ultimate Online Battery Life Calculator for IoT, Embedded Systems, and Wearable Devices</h2>
      <p class="dmc-calc-subtitle">
        Explore battery life for embedded systems with multiple modes and power rails.
      </p>
    </header>

    <!-- Example configurations -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-examples-heading">
      <h2 id="dmc-blc-examples-heading">Example configurations</h2>
      <div class="dmc-calc-field">
        <span class="dmc-calc-unit">Each link reloads this page with that template.</span>
        <p class="dmc-calc-muted">Each example demonstrates a realistic device setup, so the diagram, mode rows, and results cards line up as a teachable reference. After loading one, tweak values to see how assumptions change the life estimate.</p>
        <label id="dmc-blc-example-links-label">Load an example template</label>
        <ul class="dmc-calc-example-links" aria-labelledby="dmc-blc-example-links-label">
          <li>
            <a id="dmc-blc-example-link-coin_tracker_direct" data-example-link="coin_tracker_direct" href="#">Coin-cell tracker (direct battery)</a>
            <p class="dmc-calc-example-blurb">A simple one-cell CR2032 design with no intermediate rails, so the block diagram shows Battery feeding each load directly. Use this to see how tiny idle current and very short, frequent BLE pulses combine, then compare with the rare long beeper event to understand which activity actually dominates life.</p>
          </li>
          <li>
            <a id="dmc-blc-example-link-aa_logger_buckboost" data-example-link="aa_logger_buckboost" href="#">2xAA remote logger (buck-boost)</a>
            <p class="dmc-calc-example-blurb">Two AA alkaline cells feed a 3V3 buck-boost rail in switching 2-point efficiency mode, so the diagram includes one converter stage between battery and loads. This example helps you inspect how light-load efficiency and converter overhead affect average power during long idle windows, short samples, and periodic radio uplink bursts.</p>
          </li>
          <li>
            <a id="dmc-blc-example-link-aaa_beacon_boost" data-example-link="aaa_beacon_boost" href="#">1xAAA sensor beacon (boost)</a>
            <p class="dmc-calc-example-blurb">A single AAA cell powers a 3V0 boost rail with 2-point efficiency, representing a common ultra-low-power beacon architecture. Look at the mode table to compare near-zero idle current, periodic sensing, and brief BLE transmit pulses, then check how boost efficiency at low current impacts the final battery-life estimate.</p>
          </li>
          <li>
            <a id="dmc-blc-example-link-lipo_wearable_multirail" data-example-link="lipo_wearable_multirail" href="#">LiPo wearable (multi-rail)</a>
            <p class="dmc-calc-example-blurb">This model uses a 1S LiPo pack with a 3V3 buck rail and cascaded 1V8 core plus 2V8 sensor rails, so the diagram demonstrates a realistic multi-rail wearable tree. Use it to see how cascaded conversion losses and mixed digital/radio/sensor activity shape average power across continuous sensing and bursty communication modes.</p>
          </li>
          <li>
            <a id="dmc-blc-example-link-smart_lock_motor_boost" data-example-link="smart_lock_motor_boost" href="#">LiPo smart lock (motor boost rail)</a>
            <p class="dmc-calc-example-blurb">A 1S LiPo supply drives low-power logic rails and a separate 5V boost rail for a high-current motor, which makes the block diagram and duty-cycle math more event-driven. This example is useful for learning how rare but heavy actuation pulses can outweigh long standby periods in total energy budget.</p>
          </li>
        </ul>
      </div>
    </section>

    <section class="dmc-calc-section" aria-labelledby="dmc-blc-project-heading">
      <h2 id="dmc-blc-project-heading">Project</h2>
      <div class="dmc-calc-battery-grid">
        <div class="dmc-calc-field">
          <label for="dmc-blc-project-name">Project / device name</label>
          <input id="dmc-blc-project-name" type="text" placeholder="Example: Soil sensor v2" />
          <span class="dmc-calc-unit">Optional, not used in calculations.</span>
        </div>
      </div>
      <div class="dmc-calc-share-row" style="margin-top:0.5rem;">
        <button type="button" id="dmc-blc-copy-link" class="dmc-calc-button" disabled aria-describedby="dmc-blc-share-status">
          Copy shareable link
        </button>
        <input
          id="dmc-blc-share-url"
          type="text"
          placeholder="Project name required to enable sharing."
          readonly
        />
      </div>
      <div id="dmc-blc-share-status" class="dmc-calc-share-status">
        Enter a project name to enable sharing.
      </div>
    </section>

<!-- Battery configuration -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-battery-heading">
      <h2 id="dmc-blc-battery-heading">Battery configuration</h2>
      <div class="dmc-calc-battery-grid">
        <div class="dmc-calc-field">
          <label for="dmc-blc-batt-chemistry">Battery chemistry</label>
          <select id="dmc-blc-batt-chemistry">
            <option value="">Generic flat (avg voltage)</option>
            <option value="generic_linear">Generic linear (min/max to 0 V)</option>
            <option value="alkaline">Alkaline (AA/AAA)</option>
            <option value="cr2032">Coin cell (CR2032)</option>
            <option value="liion">Li-ion (4.2-3.0 V)</option>
            <option value="lifepo4">LiFePO4 (3.6-2.5 V)</option>
            <option value="litc">Li-SOCl2 primary (3.6-2.5 V)</option>
          </select>
          <span class="dmc-calc-unit">Chemistry + min/max voltages control derating.</span>
        </div>

        <div class="dmc-calc-field">
          <label for="dmc-blc-num-cells">Number of cells (series)</label>
          <input id="dmc-blc-num-cells" type="number" min="1" step="1" />
          <span class="dmc-calc-unit">cells</span>
        </div>

        <div class="dmc-calc-field">
          <label for="dmc-blc-cell-capacity">Cell capacity</label>
          <input id="dmc-blc-cell-capacity" type="number" min="0" step="1" />
          <span class="dmc-calc-unit">mAh</span>
        </div>

        <div class="dmc-calc-field">
          <label for="dmc-blc-cell-voltage">Average cell voltage</label>
          <input id="dmc-blc-cell-voltage" type="number" min="0" step="0.0001" />
          <span class="dmc-calc-unit">V</span>
        </div>

        <div class="dmc-calc-field" data-chem-advanced>
          <label for="dmc-blc-batt-vmax">Cell max voltage (V)</label>
          <input id="dmc-blc-batt-vmax" type="number" min="0" step="0.01" />
          <span class="dmc-calc-unit">V/cell</span>
        </div>

        <div class="dmc-calc-field" data-chem-advanced>
          <label for="dmc-blc-batt-vmin">Cell min voltage (V)</label>
          <input id="dmc-blc-batt-vmin" type="number" min="0" step="0.01" />
          <span class="dmc-calc-unit">V/cell at cutoff</span>
        </div>
      </div>
      <p class="dmc-calc-muted">
        Pack energy is computed as: Pack_mWh = CellCapacity_mAh * AvgCellVoltage_V * NumCells.
      </p>
      <details open class="dmc-calc-collapsible" aria-labelledby="dmc-blc-chem-curve-summary">
        <summary><h2 id="dmc-blc-chem-curve-summary">Discharge curve &amp; pack stats</h2></summary>
        <div class="dmc-calc-chem-curve" aria-live="polite">
          <div class="dmc-calc-chem-curve-header">
            <div>
              <h3>Discharge curve preview</h3>
              <p class="dmc-calc-muted" style="margin: 0;">
                Normalized capacity (0% = fresh cell, 100% = fully discharged).
              </p>
            </div>
            <div class="dmc-calc-chem-curve-legend">
              <span id="dmc-blc-chem-curve-label">Select a chemistry to view its curve.</span>
              <span id="dmc-blc-chem-curve-stats"></span>
            </div>
          </div>
          <canvas
            id="dmc-blc-chem-curve"
            width="720"
            height="280"
            role="img"
            aria-label="Battery discharge curve visualization"
          ></canvas>
          <p id="dmc-blc-chem-curve-note" class="dmc-calc-chem-curve-note dmc-calc-muted"></p>
          <div class="dmc-calc-chem-curve-stats">
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Pack energy max (mWh / Wh)</span>
              <span id="dmc-blc-pack-energy-full" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Pack avg voltage</span>
              <span id="dmc-blc-pack-avg" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Pack max voltage</span>
              <span id="dmc-blc-pack-max" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Pack min voltage</span>
              <span id="dmc-blc-pack-min" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Pack energy usable (mWh / Wh)</span>
              <span id="dmc-blc-pack-energy" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
            <div>
              <span class="dmc-calc-chem-curve-stat-label">Usable capacity fraction</span>
              <span id="dmc-blc-pack-usable-fraction" class="dmc-calc-chem-curve-stat-value">&#8212;</span>
            </div>
          </div>
        </div>
      </details>
    </section>

    <!-- Rails definition -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-rails-heading">
      <details open class="dmc-calc-collapsible" aria-labelledby="dmc-blc-rails-heading">
        <summary><h2 id="dmc-blc-rails-heading">Power rails</h2></summary>
        <p class="dmc-calc-muted">
          Define each rail once, including its voltage, regulator model, and optional parent rail to
          model cascaded conversion. Use <strong>Switching (fixed)</strong> for a single efficiency point, <strong>Switching (2-point)</strong>
          for low/high efficiency versus current, and <strong>Linear (LDO)</strong> to enter quiescent current (Iq).
          Rails are treated as on by demand: Iq is applied only in modes where downstream load current is non-zero.
          The calculator also shows a nominal path efficiency back to the battery.
        </p>

        <div class="dmc-calc-table-wrapper">
          <table class="dmc-calc-table dmc-calc-rails-table" aria-describedby="dmc-blc-rails-heading">
            <thead>
              <tr>
                <th>Parent rail</th>
                <th>Rail name</th>
                <th>Volts</th>
                <th>Regulator</th>
                <th>Params</th>
                <th>Path Efficiency</th>
                <th>Notes</th>
                <th></th>
              </tr>
            </thead>
            <tbody id="dmc-blc-rails-tbody">
              <tr data-rail-row data-rail-id="battery">
                <td><select aria-label="Parent rail" data-rail-field="parent" disabled aria-disabled="true"><option value="">Battery (pack root)</option></select></td>
                <td><input type="text" value="Battery rail" aria-label="Rail name" readonly aria-readonly="true" data-rail-field="name" /></td>
                <td><input type="number" min="0" step="0.01" value="3.0" aria-label="Rail voltage" readonly aria-readonly="true" data-rail-field="voltage" /></td>
                <td>
                  <select id="eff-mode-battery" class="dmc-calc-rails-eff-mode-hidden" data-rail-field="eff-mode" aria-label="Regulator model" disabled aria-disabled="true">
                    <option value="switching-simple" selected></option>
                  </select>
                </td>
                <td class="dmc-calc-rails-eff-cell">
                  <span class="dmc-calc-muted">N/A</span>
                </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="Direct battery loads" aria-label="Rail notes" readonly aria-readonly="true" data-rail-field="notes" /></td>
                <td></td>
              </tr>
              <tr data-rail-row data-rail-id="sensor">
                <td><select aria-label="Parent rail" data-rail-field="parent"><option value="battery">Battery</option></select></td>
                <td><input type="text" value="Sensor rail" aria-label="Rail name" data-rail-field="name" /></td>
                <td><input type="number" min="0" step="0.01" aria-label="Rail voltage" data-rail-field="voltage" /></td>
                <td>
                  <select data-rail-field="eff-mode" aria-label="Regulator model">
                    <option value="switching-simple" selected>Switching (fixed eff.)</option>
                    <option value="switching-2pt">Switching (2-point eff.)</option>
                    <option value="linear">Linear (LDO)</option>
                  </select>
                </td>
                <td class="dmc-calc-rails-eff-cell">
                  <div class="dmc-calc-rails-eff-rows">
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-simple-only">
                      <input type="number" min="0" max="100" step="1" aria-label="Stage efficiency (%)" inputmode="numeric" data-rail-field="efficiency" />
                      <span>%</span>
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span class="dmc-calc-rails-eff-label">Low</span>
                      <input type="number" min="0" max="100" step="1" aria-label="Low current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-low-pct" />
                      <span>% @</span>
                      <input type="number" min="0" step="0.000001" aria-label="Low current point (mA)" placeholder="mA" data-rail-field="eff-low-current" />
                      <span>mA</span>
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span class="dmc-calc-rails-eff-label">High</span>
                      <input type="number" min="0" max="100" step="1" aria-label="High current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-high-pct" />
                      <span>% @</span>
                      <input type="number" min="0" step="0.000001" aria-label="High current point (mA)" placeholder="mA" data-rail-field="eff-high-current" />
                      <span>mA</span>
                    </div>
                  </div>
                </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="e.g., ADC, sensor bias" aria-label="Rail notes" data-rail-field="notes" /></td>
                <td>
                  <button type="button" class="dmc-calc-button dmc-calc-secondary" data-remove-rail disabled aria-label="Remove rail">
                    <span aria-hidden="true">&times;</span>
                  </button>
                </td>
              </tr>
            <tr data-rail-row data-rail-id="transmitter">
              <td><select aria-label="Parent rail" data-rail-field="parent"><option value="battery">Battery</option></select></td>
              <td><input type="text" value="Transmitter rail" aria-label="Rail name" data-rail-field="name" /></td>
              <td><input type="number" min="0" step="0.01" aria-label="Rail voltage" data-rail-field="voltage" /></td>
              <td>
                <select data-rail-field="eff-mode" aria-label="Regulator model">
                  <option value="switching-simple" selected>Switching (fixed eff.)</option>
                  <option value="switching-2pt">Switching (2-point eff.)</option>
                  <option value="linear">Linear (LDO)</option>
                </select>
              </td>
              <td class="dmc-calc-rails-eff-cell">
                <div class="dmc-calc-rails-eff-rows">
                  <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-simple-only">
                    <input type="number" min="0" max="100" step="1" aria-label="Stage efficiency (%)" inputmode="numeric" data-rail-field="efficiency" />
                  </div>
                  <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                    <span>Low:</span>
                    <input type="number" min="0" max="100" step="1" aria-label="Low current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-low-pct" />
                    <span>@</span>
                    <input type="number" min="0" step="0.000001" aria-label="Low current point (mA)" placeholder="mA" data-rail-field="eff-low-current" />
                  </div>
                  <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                    <span>High:</span>
                    <input type="number" min="0" max="100" step="1" aria-label="High current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-high-pct" />
                    <span>@</span>
                    <input type="number" min="0" step="0.000001" aria-label="High current point (mA)" placeholder="mA" data-rail-field="eff-high-current" />
                  </div>
                </div>
              </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="e.g., PA boost" aria-label="Rail notes" data-rail-field="notes" /></td>
                <td>
                  <button type="button" class="dmc-calc-button dmc-calc-secondary" data-remove-rail aria-label="Remove rail">
                    <span aria-hidden="true">&times;</span>
                  </button>
                </td>
              </tr>
              <tr data-rail-row data-rail-id="receiver">
                <td><select aria-label="Parent rail" data-rail-field="parent"><option value="battery">Battery</option></select></td>
                <td><input type="text" value="Receiver rail" aria-label="Rail name" data-rail-field="name" /></td>
                <td><input type="number" min="0" step="0.01" aria-label="Rail voltage" data-rail-field="voltage" /></td>
                <td>
                  <select data-rail-field="eff-mode" class="dmc-calc-rails-eff-mode" aria-label="Regulator model">
                    <option value="switching-simple" selected>Switching (fixed eff.)</option>
                    <option value="switching-2pt">Switching (2-point eff.)</option>
                    <option value="linear">Linear (LDO)</option>
                  </select>
                </td>
                <td class="dmc-calc-rails-eff-cell">
                  <div class="dmc-calc-rails-eff-rows">
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-simple-only">
                      <input type="number" min="0" max="100" step="1" aria-label="Stage efficiency (%)" inputmode="numeric" data-rail-field="efficiency" />
                      <span>%</span>
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>Low (% @ mA):</span>
                      <input type="number" min="0" max="100" step="1" aria-label="Low current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-low-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="Low current point (mA)" placeholder="mA" data-rail-field="eff-low-current" />
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>High (% @ mA):</span>
                      <input type="number" min="0" max="100" step="1" aria-label="High current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-high-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="High current point (mA)" placeholder="mA" data-rail-field="eff-high-current" />
                    </div>
                  </div>
                </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="e.g., LNA, RX path" aria-label="Rail notes" data-rail-field="notes" /></td>
                <td>
                  <button type="button" class="dmc-calc-button dmc-calc-secondary" data-remove-rail aria-label="Remove rail">
                    <span aria-hidden="true">&times;</span>
                  </button>
                </td>
              </tr>
              <tr data-rail-row data-rail-id="core">
                <td><select aria-label="Parent rail" data-rail-field="parent"><option value="battery">Battery</option></select></td>
                <td><input type="text" value="Core rail" aria-label="Rail name" data-rail-field="name" /></td>
                <td><input type="number" min="0" step="0.01" aria-label="Rail voltage" data-rail-field="voltage" /></td>
                <td>
                  <select data-rail-field="eff-mode" class="dmc-calc-rails-eff-mode" aria-label="Regulator model">
                    <option value="switching-simple" selected>Switching (fixed eff.)</option>
                    <option value="switching-2pt">Switching (2-point eff.)</option>
                    <option value="linear">Linear (LDO)</option>
                  </select>
                </td>
                <td class="dmc-calc-rails-eff-cell">
                  <div class="dmc-calc-rails-eff-rows">
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-simple-only">
                      <input type="number" min="0" max="100" step="1" aria-label="Stage efficiency (%)" inputmode="numeric" data-rail-field="efficiency" />
                      <span>%</span>
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>Low:</span>
                      <input type="number" min="0" max="100" step="1" aria-label="Low current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-low-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="Low current point (mA)" placeholder="mA" data-rail-field="eff-low-current" />
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>High:</span>
                      <input type="number" min="0" max="100" step="1" aria-label="High current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-high-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="High current point (mA)" placeholder="mA" data-rail-field="eff-high-current" />
                    </div>
                  </div>
                </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="e.g., MCU core" aria-label="Rail notes" data-rail-field="notes" /></td>
                <td>
                  <button type="button" class="dmc-calc-button dmc-calc-secondary" data-remove-rail aria-label="Remove rail">
                    <span aria-hidden="true">&times;</span>
                  </button>
                </td>
              </tr>
              <tr data-rail-row data-rail-id="aux">
                <td><select aria-label="Parent rail" data-rail-field="parent"><option value="battery">Battery</option></select></td>
                <td><input type="text" value="Aux rail" aria-label="Rail name" data-rail-field="name" /></td>
                <td><input type="number" min="0" step="0.01" aria-label="Rail voltage" data-rail-field="voltage" /></td>
                <td>
                  <select data-rail-field="eff-mode" class="dmc-calc-rails-eff-mode" aria-label="Regulator model">
                    <option value="switching-simple" selected>Switching (fixed eff.)</option>
                    <option value="switching-2pt">Switching (2-point eff.)</option>
                    <option value="linear">Linear (LDO)</option>
                  </select>
                </td>
                <td class="dmc-calc-rails-eff-cell">
                  <div class="dmc-calc-rails-eff-rows">
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-simple-only">
                      <input type="number" min="0" max="100" step="1" aria-label="Stage efficiency (%)" inputmode="numeric" data-rail-field="efficiency" />
                      <span>%</span>
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>Low:</span>
                      <input type="number" min="0" max="100" step="1" aria-label="Low current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-low-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="Low current point (mA)" placeholder="mA" data-rail-field="eff-low-current" />
                    </div>
                    <div class="dmc-calc-rails-eff-row dmc-calc-rails-eff-adv" style="display: none;">
                      <span>High:</span>
                      <input type="number" min="0" max="100" step="1" aria-label="High current efficiency (%)" inputmode="numeric" placeholder="%" data-rail-field="eff-high-pct" />
                      <span>@</span>
                      <input type="number" min="0" step="0.000001" aria-label="High current point (mA)" placeholder="mA" data-rail-field="eff-high-current" />
                    </div>
                  </div>
                </td>
                <td><span data-rail-effective>&#8212; %</span></td>
                <td><input type="text" placeholder="e.g., LEDs, misc" aria-label="Rail notes" data-rail-field="notes" /></td>
                <td>
                  <button type="button" class="dmc-calc-button dmc-calc-secondary" data-remove-rail aria-label="Remove rail">
                    <span aria-hidden="true">&times;</span>
                  </button>
                </td>
              </tr>
            </tbody>
          </table>
        </div>

        <div class="dmc-calc-modes-actions">
          <button type="button" id="dmc-blc-add-rail" class="dmc-calc-button">
            Add rail
          </button>
          <span class="dmc-calc-muted">
            Enter voltage and regulator parameters per rail so the calculator can translate per-mode currents into battery power.
          </span>
        </div>
      </details>
    </section>

    <!-- Loads definition -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-loads-heading">
      <details open class="dmc-calc-collapsible" aria-labelledby="dmc-blc-loads-heading">
        <summary><h2 id="dmc-blc-loads-heading">Loads (peripherals)</h2></summary>
        <p class="dmc-calc-muted">
          Define generic loads such as MCU, sensor, transmitter, or receiver. Each load is powered from one of the
          rails above and appears as a column in the modes table.
        </p>

        <div class="dmc-calc-table-wrapper">
        <table class="dmc-calc-table dmc-calc-loads-table" aria-describedby="dmc-blc-loads-heading">
          <thead>
            <tr>
              <th>Load name</th>
              <th>Rail</th>
              <th>Notes</th>
                <th></th>
              </tr>
            </thead>
            <tbody id="dmc-blc-loads-tbody">
              <!-- Initial loads are seeded from rails in JavaScript -->
            </tbody>
          </table>
        </div>

        <div class="dmc-calc-modes-actions">
          <button type="button" id="dmc-blc-add-load" class="dmc-calc-button">
            Add load
          </button>
          <span class="dmc-calc-muted">
          Loads inherit voltage and cascaded efficiency from their rail; change the rail to move a load between rails.
          </span>
        </div>
      </details>
    </section>

    <section class="dmc-calc-section" aria-labelledby="dmc-blc-topology-heading">
      <details open class="dmc-calc-collapsible" aria-labelledby="dmc-blc-topology-heading">
        <summary><h2 id="dmc-blc-topology-heading">Block diagram</h2></summary>
        <div class="dmc-calc-topology">
          <svg id="dmc-blc-topology-svg" role="img" aria-label="Power rails and loads topology"></svg>
          <p class="dmc-calc-muted" style="margin-top: 0.4rem;">
            Diagram auto-generates from your rails (columns) and loads (final column). Parent rails feed child rails and loads.
          </p>
        </div>
      </details>
    </section>

    <!-- Modes and loads -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-modes-heading">
      <details open class="dmc-calc-collapsible" aria-labelledby="dmc-blc-modes-heading">
        <summary><h2 id="dmc-blc-modes-heading">Modes, timing, and load currents</h2></summary>
        <p class="dmc-calc-muted">
          The <strong>first row (Idle)</strong> is always on and fills any time not used by other modes.
          Add additional modes such as Sensor sample, Transmitter burst, and Receiver listen by clicking &#8220;Add mode&#8221; below.
          Each mode specifies a current for each load during its active time; loads inherit voltage and efficiency from their rails above.
        </p>

      <div class="dmc-calc-table-wrapper">
        <table class="dmc-calc-table dmc-calc-modes-table" aria-describedby="dmc-blc-modes-heading">
          <thead id="dmc-blc-modes-thead"></thead>
          <tbody id="dmc-blc-modes-tbody"></tbody>
        </table>
      </div>

      <div class="dmc-calc-modes-actions">
        <button type="button" id="dmc-blc-add-mode" class="dmc-calc-button">
          Add mode
        </button>
        <span class="dmc-calc-muted">
          Modes share a single comparison period based on the longest configured period.
        </span>
      </div>
      <div id="dmc-blc-timing-warning" class="dmc-calc-warning" style="display:none;" role="status" aria-live="polite"></div>
      </details>
    </section>

    <!-- Results -->
    <section class="dmc-calc-section" aria-labelledby="dmc-blc-results-heading">
      <h2 id="dmc-blc-results-heading">Results</h2>
      <div class="dmc-calc-results-grid">
        <div class="dmc-calc-card">
          <h3>Average power</h3>
          <div class="dmc-calc-card-value" id="dmc-blc-avg-power-total">&#8212; uW</div>
          <div class="dmc-calc-card-sub">Time-weighted average across all modes.</div>
        </div>

        <div class="dmc-calc-card">
          <h3>Battery life (hours)</h3>
          <div class="dmc-calc-card-value" id="dmc-blc-life-hours">&#8212; h</div>
          <div class="dmc-calc-card-sub">Based on pack energy and average power.</div>
        </div>

        <div class="dmc-calc-card">
          <h3>Battery life (days / years)</h3>
          <div class="dmc-calc-card-value">
            <span id="dmc-blc-life-days">&#8212; days</span>,
            <span id="dmc-blc-life-years">&#8212; years</span>
          </div>
          <div class="dmc-calc-card-sub">Converted from hours for convenience.</div>
        </div>
      </div>
      <p class="dmc-calc-muted">
        Mode duty, average power, and contribution are shown per row in the modes table above. The chart
        below visualizes how much each mode contributes to the overall average power.
      </p>
      <div class="dmc-calc-mode-bars" aria-label="Mode contribution breakdown">
        <h3>Mode contributions</h3>
        <div id="dmc-blc-mode-bars-body" class="dmc-calc-mode-bars-body">
          <div class="dmc-calc-muted">
            Enter timing and currents above to see how each mode contributes to the total average power.
          </div>
        </div>
      </div>
    </section>

    <script id="dmc-blc-debug-payload" type="application/json" hidden></script>

<!-- Explanation -->
    <section class="dmc-calc-section">
      <div class="dmc-calc-explainer">
        <h2>How this calculator works (conceptually)</h2>
        <p><strong>Big picture</strong>: this is an estimator, not a simulator. It gives a defensible, first-order answer for &#8220;how long will my thing run?&#8221; and teaches how duty cycle, rails, and efficiency play together. Measure on hardware once you have a prototype.</p>
        <div class="dmc-calc-concepts-grid" style="margin-top:0.5rem;">
          <div class="dmc-calc-concept-card">
            <p class="dmc-calc-concept-name">1. Pack energy</p>
            <p class="dmc-calc-concept-detail">
              <em>Energy bucket</em> The model converts battery specs into one budget number:
              <code>Pack_mWh = CellCapacity_mAh * AvgCellVoltage_V * NumCells</code>. This is the full bucket before cutoff and
              chemistry derating.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>How usable energy is estimated</em> For named chemistries with valid min/max cell voltage, the model applies a
              chemistry profile to compute a usable fraction and then uses
              <code>UsablePackEnergy_mWh = Pack_mWh * usable_capacity_fraction</code>. If chemistry or cutoff data is missing, it
              falls back to <code>usable_capacity_fraction = 1</code> instead of guessing.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Philosophy</em> This is a first-order planning model, not an electrochemical simulator. We intentionally keep one
              average-voltage energy bucket so design tradeoffs are easy to compare and assumptions stay visible.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Example</em> Two 2500 mAh alkaline cells at 1.3 V average give
              <code>Pack_mWh = 2500 * 1.3 * 2 = 6500 mWh</code>. If cutoff/chemistry gives
              <code>usable_capacity_fraction = 0.8</code>, usable energy is <code>5200 mWh</code>.
            </p>
          </div>

          <div class="dmc-calc-concept-card">
            <p class="dmc-calc-concept-name">2. Duty cycle</p>
            <p class="dmc-calc-concept-detail">
              Comparison window = longest non-idle period. Duty = <code>active_ms / (period_s * 1000)</code>. Idle duty is
              whatever time remains after non-idle modes.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Example</em> If a sensor sample runs for 250 ms every 60 s, then
              <code>Duty_sample = 250 / 60000 = 0.00417 = 0.417%</code>. If uplink runs 1200 ms every 900 s, then
              <code>Duty_uplink = 1200 / 900000 = 0.133%</code>. Idle gets the remaining time.
            </p>
          </div>

          <div class="dmc-calc-concept-card">
            <p class="dmc-calc-concept-name">3. Rail efficiency</p>
            <p class="dmc-calc-concept-detail">
              <em>Switching (fixed)</em> means one fixed efficiency for that rail: <code>efficiency = eff_pct / 100</code>. If you enter 90%,
              the model assumes about 10% of converter input power is lost as heat at all loads. <em>Switching (2-point)</em> means you enter two
              points from the regulator datasheet <em>Efficiency vs Output Current</em> graph at your expected VIN/VOUT:
              <code>(I_low, Eff_low)</code> and <code>(I_high, Eff_high)</code>. Below <code>I_low</code> the model uses
              <code>Eff_low</code>, above <code>I_high</code> it uses <code>Eff_high</code>, and between them it interpolates in
              log(current) so light-load and heavy-load behavior are both represented. Some datasheets use the Greek symbol
              <code>&eta;</code> for efficiency. <em>Linear (LDO)</em> uses <code>VIN/VOUT</code> behavior plus quiescent current:
              <code>P_in = V_in * (I_out + I_q)</code>.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Why it matters</em> Efficiency loss becomes heat, and that heat comes from your battery budget. A converter that
              is 90% efficient needs about 11% more input power than the load uses. At low currents, many converters get worse, so
              sleep-heavy products can lose more life than expected if you use one optimistic efficiency number.
            </p>
            <div class="dmc-calc-2pt-demo" role="img" aria-label="Two-point efficiency behavior with logarithmic current response">
              <svg viewBox="0 0 300 122" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
                <rect x="0" y="0" width="300" height="122" fill="#ffffff"></rect>
                <line x1="34" y1="16" x2="34" y2="94" stroke="#c9cfdb" stroke-width="1"></line>
                <line x1="34" y1="94" x2="286" y2="94" stroke="#c9cfdb" stroke-width="1"></line>
                <line x1="78" y1="16" x2="78" y2="94" stroke="#e1e6f0" stroke-width="1"></line>
                <line x1="144" y1="16" x2="144" y2="94" stroke="#e1e6f0" stroke-width="1"></line>
                <line x1="212" y1="16" x2="212" y2="94" stroke="#e1e6f0" stroke-width="1"></line>
                <path d="M42 77 C58 77, 67 77, 74 76 C94 72, 116 61, 136 50 C164 37, 192 32, 220 31 C246 31, 265 31, 278 31" fill="none" stroke="#0057b8" stroke-width="2.4"></path>
                <circle cx="74" cy="76" r="4" fill="#0057b8"></circle>
                <circle cx="220" cy="31" r="4" fill="#0057b8"></circle>
                <line x1="74" y1="16" x2="74" y2="94" stroke="#8a94a8" stroke-dasharray="4 3" stroke-width="1"></line>
                <line x1="220" y1="16" x2="220" y2="94" stroke="#8a94a8" stroke-dasharray="4 3" stroke-width="1"></line>
                <text x="54" y="107" font-size="10.5" fill="#4a4a4a">Low current</text>
                <text x="198" y="107" font-size="10.5" fill="#4a4a4a">High current</text>
                <text x="8" y="23" font-size="10" fill="#666">Efficiency (%)</text>
                <text x="204" y="118" font-size="10" fill="#666">Current (mA, log-like)</text>
              </svg>
            </div>
          </div>

          <div class="dmc-calc-concept-card">
            <p class="dmc-calc-concept-name">4. Power per mode</p>
            <p class="dmc-calc-concept-detail">
              <em>Path efficiency</em> Multiply stage efficiencies up the parent chain to get <code>PathEfficiency</code>.
              <em>Per load</em> compute rail power with
              <code>RailPower_uW = RailVoltage_V * LoadCurrent_mA * 1000</code>; battery-side power is
              <code>BatteryPower_uW = RailPower_uW / PathEfficiency</code>. <em>Per mode</em> sum battery-side load powers:
              <code>ModePower_uW = sum(BatteryPower_uW)</code>.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Why it matters</em> Cascaded regulators stack losses. If one stage is 90% and the next is 90%, the path is
              <code>0.9 * 0.9 = 0.81</code>, so only 81% of battery power reaches the load. This is why “just add another rail”
              can reduce battery life more than expected.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Analogy</em> Think of power as water moved through hoses. Each regulator is a hose section with a leak. One small
              leak might be fine, but several leaks in series mean much less water reaches the plant at the end.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Example</em> A 3.3 V rail load at 2 mA is <code>3.3 * 2 * 1000 = 6600 uW</code>. If regulator path efficiency
              is 85%, battery-side power is <code>6600 / 0.85 = 7765 uW</code>.
            </p>
          </div>

          <div class="dmc-calc-concept-card">
            <p class="dmc-calc-concept-name">5. Time weighting &amp; life</p>
            <p class="dmc-calc-concept-detail">
              <em>Weighting</em> <code>ModeAveragePower_uW = ModePower_uW * DutyFraction</code>; total
              <code>TotalAveragePower_uW = sum(ModeAveragePower_uW)</code>. <em>Life</em>
              <code>Life_h = UsablePackEnergy_mWh * 1000 / TotalAveragePower_uW</code>; UI also shows days/years.
            </p>
            <p class="dmc-calc-concept-detail">
              <em>Example</em> If sleep is 100 uW at 99% duty and active is 50,000 uW at 1% duty, then
              <code>TotalAveragePower_uW = (100 * 0.99) + (50000 * 0.01) = 599 uW</code>. With 6000 mWh usable energy,
              <code>Life_h = 6000 * 1000 / 599 = 10017 h</code> (about 417 days).
            </p>
          </div>
        </div>
<div class="dmc-calc-concepts-grid">
        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Battery chemistry &amp; capacity</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            The chemistry (alkaline, Li-ion, coin cell, etc.) sets the usable voltage range and how the cell behaves as it discharges.
            Capacity (mAh) tells you how much charge the battery can deliver at a gentle load.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            The same device can run for weeks on a tiny coin cell or years on a larger primary lithium pack. Chemistry also affects
            self‑discharge, low‑temperature behavior, and how much of the cell’s capacity is usable at higher currents.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Pick a chemistry that roughly matches your cell type. Use datasheet or application‑note values for capacity and voltage.
            Remember this tool assumes “average” voltage; it does not simulate detailed discharge curves.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            For long life, bigger is not always better. A slightly larger cell that lets your converter operate in a sweet spot
            (good efficiency, enough headroom) often buys more life than just stacking cells at random.
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Pack voltage &amp; rails</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            Pack voltage is the battery side. Rails are the local supply voltages your circuits actually use (3.3 V digital, 5 V sensor
            bias, 1.8 V core, and so on). Regulators connect the pack to each rail.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            Every time you convert from the pack to a rail you lose some power in the regulator. Cascaded rails multiply those losses.
            A “simple” rail with 90% efficiency wastes 10% of its input power as heat.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Define one row per regulated rail. Use <strong>Switching (fixed eff.)</strong> when you only know one converter efficiency,
            <strong>Switching (2-point eff.)</strong> when data sheets give light-load and heavy-load points, and
            <strong>Linear (LDO)</strong> when you know VIN, VOUT, and quiescent current (Iq).
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            Avoid unnecessary rails and unnecessary cascades. For example, powering a low‑current MCU from a linear regulator off a
            switching pre‑regulator can be fine, but putting a linear on top of another linear wastes a lot of energy.
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">2-point efficiency model</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            Real DC‑DC converters are not flat. They are usually less efficient at very light load, peak somewhere in the middle,
            and droop again near the current limit. Measuring or estimating the full curve is hard.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            Many IoT devices spend most of their life sipping microamps, then wake up to tens of milliamps briefly. A single
            “typical” efficiency value hides how different those regimes are.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Enter a “Low” point (efficiency and current) and a “High” point. The calculator interpolates between them on a log
            current axis so you get a reasonable effective efficiency for each mode’s load current without a full curve.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            When choosing converters, pay attention to efficiency near your dominant operating currents, not just the headline peak.
            A part that is fantastic at 500 mA but poor at 10 µA may be the wrong choice for a sleepy sensor node.
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Modes &amp; duty cycle</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            A mode is a named behavior: “Idle,” “Sense,” “Transmit,” “OTA update,” and so on. Each mode has a period (how often it
            happens) and an active time (how long it lasts when it happens).
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            Average power is dominated by the product of power and duty cycle. A very expensive‑looking transmit burst that happens
            for 2 ms once per minute can cost less energy than a “tiny” background current that flows all the time.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Enter realistic periods and active times for each behavior. You can select timing units per row
            (ms, s, m, h, d), and the duty column is computed for you from the effective values.
            OTA‑style events can be modeled with long periods (hours, days, months) and finite active times.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            Design your firmware so that the system spends most of its life in the lowest‑power mode possible. Shorten active time,
            reduce how often expensive modes run, and move work into batch operations instead of frequent small bursts.
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Idle mode &amp; background current</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            “Idle” is the mode where nothing interesting happens: MCU in sleep, radios off, only keep‑alive circuits running.
            The calculator treats idle specially and fills any time that is not used by other modes.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            In many IoT designs, idle dominates energy use. Shaving microamps off idle current can extend life more than tweaking
            a high‑power burst that only happens occasionally.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            The first mode row is fixed as Idle and cannot be removed. Put your sleep/background currents in that row;
            its timing is auto-computed as whatever time remains after non-idle modes.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            Turn off unneeded clocks and peripherals, use deep‑sleep states where possible, and make sure regulators are still
            efficient at your idle currents. Datasheet “off currents” for sensors and radios are often surprisingly high.
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Loads &amp; current estimates</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            Loads are the things that draw current on each rail: MCU, radio, sensor front‑end, LEDs, USB, buzzers, and so on. Each
            load can be active or mostly off depending on the mode.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            Mode current is rarely just “one number.” Splitting by load lets you see which pieces dominate energy use, and how
            moving a load to a different rail or changing hardware affects the whole system.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Create a load per major block and assign it to a rail. For each mode, enter the current that block draws while the
            mode is active. Use data sheets, evaluation boards, or quick bench measurements as a starting point.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to optimize</em>
            Look for loads that are on in many modes but do not always need to be. Can a sensor be duty‑cycled? Can LEDs flash more
            briefly? Can a radio use a lower TX power in some modes?
          </p>
        </div>

        <div class="dmc-calc-concept-card">
          <p class="dmc-calc-concept-name">Estimator vs. real hardware</p>
          <p class="dmc-calc-concept-detail">
            <em>What it is</em>
            A structured way to do the back‑of‑the‑envelope math you would otherwise keep in a spreadsheet or notebook. It does not
            know about temperature, aging, or detailed battery curves.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>Why it matters</em>
            The goal is to be “right enough” to compare designs and guide experiments: choose between chemistries, rail topologies,
            firmware strategies, and component options before you build hardware.
          </p>
          <p class="dmc-calc-concept-detail">
            <em>How to use it here</em>
            Explore “what if?” questions: What if the radio wakes up twice as often? What if I change the sensor regulator from an
            LDO to a buck? How much life do I lose if my idle current doubles?
          </p>
          <p class="dmc-calc-concept-detail">
            <em>What to verify</em>
            Once you have a prototype, measure currents for each mode and update the model. If estimates and measurements disagree
            by a lot, that is a great learning opportunity—look for missing loads, sleep bugs, and efficiency assumptions.
          </p>
        </div>
      </div>
    </section>
  </div>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Ready to Maximize Battery Performance?</strong> See How DMC Can Get You Started.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">DMC can help optimize battery-powered products with system design. Learn more about how our <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded</a> team can help with your battery functions.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/41922/battery-life-calculator/">Battery Life Calculator</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>UART vs RS-232: Understanding the Differences</title>
		<link>https://static.dmcinfo.com/blog/41558/uart-vs-rs-232-understanding-the-differences/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Wed, 04 Mar 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=41558</guid>

					<description><![CDATA[<p>In the world of embedded development and industrial automation, terminology is often used loosely. It is&#160;very common&#160;to hear &#8220;UART&#8221;&#160;and &#8220;RS-232&#8221; used as synonyms in casual technical discussions.&#160; For example, a requirement might call for an &#8220;RS-232 interface.&#8221; However, after clarifying the technical details, the actual need might be a simple logic-level connection for debugging or [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/41558/uart-vs-rs-232-understanding-the-differences/">UART vs RS-232: Understanding the Differences</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In the world of <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/">embedded development</a> and industrial automation, terminology is often used loosely. It is&nbsp;very common&nbsp;to hear &#8220;UART&#8221;&nbsp;and &#8220;RS-232&#8221; used as synonyms in casual technical discussions.&nbsp;</p>



<p class="wp-block-paragraph">For example, a requirement might call for an &#8220;RS-232 interface.&#8221; However, after clarifying the technical details, the actual need might be a simple logic-level connection for debugging or communication between microcontrollers on the same circuit board.&nbsp;</p>



<p class="wp-block-paragraph">To a Firmware or Hardware Engineer, these terms&nbsp;represent&nbsp;two different layers of communication: the&nbsp;protocol&nbsp;(the logic) and the&nbsp;physical interface&nbsp;(the voltage, pinout,&nbsp;and cabling). Distinguishing between them helps ensure that hardware specifications match the actual system requirements and&nbsp;leads&nbsp;to smoother integration.&nbsp;</p>



<p class="wp-block-paragraph">Let’s&nbsp;look at the difference between the logic of the conversation (UART) and the physical medium it travels through (RS-232).&nbsp;</p>



<h2 id="h-uart" class="wp-block-heading">UART</h2>



<p class="wp-block-paragraph">UART&nbsp;stands for&nbsp;Universal Asynchronous Receiver-Transmitter.&nbsp;</p>



<p class="wp-block-paragraph">Strictly speaking, a UART is not a communication standard like Wi-Fi or Ethernet.&nbsp;It is&nbsp;usually&nbsp;a hardware peripheral block inside a microcontroller (MCU). Its job is to format&nbsp;data. It takes parallel bytes from the CPU and serializes them into a stream of bits, framing them with start bits, stop bits, and optional parity&nbsp;to be transmitted via a pin.&nbsp;</p>



<p class="wp-block-paragraph">When a UART transmits data directly from the&nbsp;microcontroller’s&nbsp;pins, the signal exists at&nbsp;Logic Levels. Historically, these were known as&nbsp;TTL&nbsp;(Transistor-Transistor Logic) levels, which typically&nbsp;operated&nbsp;at&nbsp;5V. Modern microcontrollers, however, are predominantly operating&nbsp;at lower voltages like&nbsp;3.3V&nbsp;or&nbsp;1.8V.&nbsp;</p>



<p class="wp-block-paragraph">Because of these voltage differences, compatibility is a key consideration. Connecting a legacy 5V signal directly to a modern 3.3V microcontroller can damage internal circuitry. It is worth verifying if specific pins&nbsp;can handle 5V signals. If&nbsp;not,&nbsp;you’ll&nbsp;have to create&nbsp;a&nbsp;logic&nbsp;level&nbsp;shifter&nbsp;to bridge the two voltage domains safely.&nbsp;</p>



<p class="wp-block-paragraph">In practice, UART is the workhorse of&nbsp;on-board communication.&nbsp;It is used&nbsp;to connect the main microcontroller to peripherals located on the same PCB:&nbsp;such as Wi-Fi modules, GPS receivers, modems, etc.&nbsp;</p>



<p class="wp-block-paragraph">It is also the primary interface for hardware bring-up and debugging, allowing developers to view system logs and interact with the firmware via a simple serial terminal.&nbsp;</p>



<p class="wp-block-paragraph">For this purpose, a&nbsp;USB‑to‑UART adapter becomes an essential tool. These adapters allow a developer to&nbsp;connect&nbsp;a PC directly to the microcontroller’s UART pins&nbsp;using a standard USB port.&nbsp;On the PC side, the adapter&nbsp;enumerates&nbsp;as a virtual COM port, which can be accessed using common terminal programs such as&nbsp;<a href="https://sourceforge.net/projects/realterm/" target="_blank" rel="noreferrer noopener">RealTerm</a>.&nbsp;On the hardware side, the adapter outputs logic‑level UART signals (typically 3.3 V or 5 V), making it safe to connect directly to a PCB’s debug header.&nbsp;One of the examples of such USB-UART adapters is presented below.&nbsp;</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="699" height="354" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-UART-adapter.jpg" alt="Red and black USB-UART adapter" class="wp-image-41578" style="border-radius:20px;width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-UART-adapter.jpg 699w, https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-UART-adapter-300x152.jpg 300w" sizes="(max-width: 699px) 100vw, 699px" /><figcaption class="wp-element-caption"><em>Standard USB-UART adapter</em></figcaption></figure>



<h2 id="h-usart-universal-synchronous-asynchronous-receiver-transmitter-nbsp" class="wp-block-heading">USART (Universal Synchronous/Asynchronous Receiver-Transmitter)&nbsp;</h2>



<p class="wp-block-paragraph">If you look at datasheets from manufacturers like STMicroelectronics or Microchip, you will often see the peripheral labeled as&nbsp;USART. The &#8220;S&#8221; stands for&nbsp;Synchronous, meaning the hardware&nbsp;<em>can</em>&nbsp;support a clock line (CLK). Therefore, such USART peripherals can be configured to&nbsp;support&nbsp;common&nbsp;Synchronous&nbsp;protocols,&nbsp;such as&nbsp;SPI&nbsp;(Serial Peripheral Interface), and others. However, this peripheral&nbsp;can also&nbsp;be configured&nbsp;in&nbsp;Asynchronous&nbsp;mode, where it behaves exactly like a standard&nbsp;UART.&nbsp;</p>



<h2 id="h-rs-232-nbsp" class="wp-block-heading">RS-232&nbsp;</h2>



<p class="wp-block-paragraph"><strong>RS-232</strong>&nbsp;(Recommended Standard 232) defines the&nbsp;physical interface. It describes&nbsp;<em>how</em>&nbsp;the data is electrically transmitted to work reliably over cables in the &#8220;outside world,&#8221; away from the protection of the PCB.&nbsp;</p>



<p class="wp-block-paragraph">RS-232 transmits the same data packet as the UART, but with two major physical differences designed to improve noise immunity over longer cables.&nbsp;</p>



<ol class="wp-block-list">
<li>Voltage Levels &#8211;&nbsp;RS-232 uses bipolar signals. A valid signal typically ranges from&nbsp;±3V to ±15V.&nbsp;</li>



<li>Signal Inversion&nbsp;&#8211;&nbsp;This is a common point of confusion. The logic is inverted compared to UART:&nbsp;
<ul class="wp-block-list">
<li>Logic &#8216;1&#8217; (Mark)&nbsp;is represented by a&nbsp;Negative&nbsp;voltage (e.g., -12V).&nbsp;</li>



<li>Logic &#8216;0&#8217; (Space)&nbsp;is<strong>&nbsp;</strong>represented by a&nbsp;Positive&nbsp;voltage (e.g., +12V).&nbsp;</li>



<li>Therefore,&nbsp;while the UART signal idles High (Vcc), the RS-232 signal&nbsp;idles&nbsp;Low (Negative Voltage).&nbsp;</li>
</ul>
</li>
</ol>



<p class="wp-block-paragraph">Despite its age, RS-232&nbsp;remains&nbsp;ubiquitous in industrial and commercial environments due to its robustness and simplicity. It&nbsp;can&nbsp;be&nbsp;found in industrial automation for programming PLCs&nbsp;(Programmable Logic Controllers),&nbsp;other&nbsp;industrial and scientific equipment. Additionally, RS-232 serves as the standard &#8220;Console&#8221; interface on&nbsp;some&nbsp;networking equipment,&nbsp;Point of Sale (POS) peripherals like receipt printers and barcode scanners.</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="900" height="601" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/Receipt-Printer.jpg" alt="Receipt printer on a wooden table" class="wp-image-41581" style="border-radius:20px;width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/Receipt-Printer.jpg 900w, https://static.dmcinfo.com/wp-content/uploads/2026/02/Receipt-Printer-300x200.jpg 300w, https://static.dmcinfo.com/wp-content/uploads/2026/02/Receipt-Printer-768x513.jpg 768w" sizes="(max-width: 900px) 100vw, 900px" /><figcaption class="wp-element-caption"><em><em>Receipt printer with an RS-232 cable&nbsp;(DE9/DB9&nbsp;connector)</em>&nbsp;</em></figcaption></figure>



<p class="wp-block-paragraph">RS-232 ports used to be built&nbsp;into&nbsp;most PCs&nbsp;and laptops, but not anymore.&nbsp;Therefore,&nbsp;to&nbsp;interface modern computers with&nbsp;legacy equipment, a USB‑to‑RS‑232 adapter is typically used. These adapters bridge the gap between&nbsp;modern&nbsp;USB&nbsp;port&nbsp;and RS‑232 devices. On the PC side, the adapter appears as a virtual COM port&nbsp;to allow unified communication with RS-232 devices.&nbsp;Most USB-to-RS-232 adapters&nbsp;terminate&nbsp;in a&nbsp;9pin DE9 connector&nbsp;(<a href="https://news.sparkfun.com/14298">commonly referred to as DB9</a>).</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="620" height="543" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-to-RS-232-adapter.jpg" alt="USB-to-RS-232 adapter" class="wp-image-41586" style="border-radius:20px;width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-to-RS-232-adapter.jpg 620w, https://static.dmcinfo.com/wp-content/uploads/2026/02/USB-to-RS-232-adapter-300x263.jpg 300w" sizes="(max-width: 620px) 100vw, 620px" /><figcaption class="wp-element-caption"><em>USB-to-RS-232 adapter. Note the DE9/DB9 connector.</em></figcaption></figure>



<p class="wp-block-paragraph">It is worth noting that&nbsp;while the modern standard is the 9-pin DE9 (often called&nbsp;DB9) connector, the original standard defined a 25-pin connector (DB25),&nbsp;which you can&nbsp;still&nbsp;find on&nbsp;some&nbsp;very&nbsp;legacy devices.&nbsp;&nbsp;</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="867" height="281" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB9-pinout.png" alt="" class="wp-image-41583" style="width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB9-pinout.png 867w, https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB9-pinout-300x97.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB9-pinout-768x249.png 768w" sizes="(max-width: 867px) 100vw, 867px" /><figcaption class="wp-element-caption"><em><em>RS-232 DE9/DB9 pinout</em></em></figcaption></figure>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="870" height="834" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB25-pinout.png" alt="RS-232 DB25 pinout" class="wp-image-41585" style="width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB25-pinout.png 870w, https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB25-pinout-300x288.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-DB25-pinout-768x736.png 768w" sizes="(max-width: 870px) 100vw, 870px" /><figcaption class="wp-element-caption"><em><em>RS-232 DB25 pinout</em></em></figcaption></figure>



<h2 id="h-connecting-uart-to-rs-232" class="wp-block-heading">Connecting UART to RS-232</h2>



<p class="wp-block-paragraph">Since a microcontroller cannot natively generate negative voltages or handle 12V signals,&nbsp;we cannot wire a standard&nbsp;RS-232&nbsp;DE9 connector directly to the MCU. To implement an&nbsp;RS-232 interface, we use a&nbsp;Transceiver&nbsp;IC&nbsp;(such as the industry-standard MAX232 or similar).&nbsp;</p>



<ol start="1" class="wp-block-list">
<li>MCU Side&nbsp;&#8211;&nbsp;The UART peripheral is configured to use&nbsp;TX&nbsp;(Transmit) and&nbsp;RX&nbsp;(Receive) pins at&nbsp;MCU&nbsp;logic levels.&nbsp;</li>



<li>Transceiver&nbsp;&#8211;&nbsp;The&nbsp;transceiver IC&nbsp;(MAX232&nbsp;or similar) sits between the MCU and the&nbsp;RS-232&nbsp;connector. It generates the required high voltages and handles&nbsp;the signal&nbsp;conversion.&nbsp;</li>



<li>Connector&nbsp;&#8211;&nbsp;The transceiver&nbsp;IC&nbsp;outputs standard RS-232 signals to the port (DE9 connector).&nbsp;</li>
</ol>



<p class="wp-block-paragraph">Such adapters are available as standalone&nbsp;boards that you can use for quick prototyping and experimentation. One&nbsp;of the options is presented&nbsp;below.&nbsp;</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="727" height="754" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-to-UART-adapter.jpg" alt="RS-232 to UART adapter" class="wp-image-41588" style="border-radius:20px;width:450px" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-to-UART-adapter.jpg 727w, https://static.dmcinfo.com/wp-content/uploads/2026/02/RS-232-to-UART-adapter-289x300.jpg 289w" sizes="(max-width: 727px) 100vw, 727px" /><figcaption class="wp-element-caption"><em>RS-232 to UART adapter</em></figcaption></figure>



<h2 id="h-flow-control-and-pinout" class="wp-block-heading">Flow Control and Pinout</h2>



<p class="wp-block-paragraph">Many common integrations often only require a minimal connection consisting of&nbsp;TX, RX, and&nbsp;Ground. In these cases, software flow control (referred as&nbsp;XON/XOFF) is sometimes used&nbsp;to prevent&nbsp;sending too much data too fast and overflowing the receiver’s buffer, or the data rate is&nbsp;just&nbsp;low enough&nbsp;and the receiver can handle it fast enough&nbsp;that buffers do not overflow.&nbsp;</p>



<p class="wp-block-paragraph">However,&nbsp;Hardware Flow Control&nbsp;is not just a relic of the past. It is widely used in modern&nbsp;equipment&nbsp;to ensure data integrity. In this scenario, the firmware engineer configures two&nbsp;additional&nbsp;pins:&nbsp;RTS&nbsp;(Request to Send) and&nbsp;CTS&nbsp;(Clear to Send). These signals are also routed through the transceiver to help manage&nbsp;the data&nbsp;flow.&nbsp;These signals are standard&nbsp;on&nbsp;both&nbsp;DE9 and DB25 RS-232 connectors.&nbsp;</p>



<h2 id="h-cabling-nbsp-configuration-dte-vs-dce" class="wp-block-heading">Cabling&nbsp;Configuration: DTE vs. DCE</h2>



<p class="wp-block-paragraph">Another common pitfall involves cabling. The RS-232 standard historically distinguishes between&nbsp;Data Terminal Equipment (DTE), such as computers, and&nbsp;Data Communication Equipment (DCE), such as modems. While a straight-through cable connects a DTE to a DCE, connecting two DTE devices directly (e.g., a PC to an embedded system) requires a&nbsp;Null Modem&nbsp;cable or adapter to cross the&nbsp;transmit&nbsp;and receive lines correctly.&nbsp;</p>



<p class="wp-block-paragraph">On a related note,&nbsp;when connecting two&nbsp;UART&nbsp;devices, it is crucial to remember the&nbsp;crossover rule: the TX pin of the transmitting device must connect to the RX pin of the receiving device, and vice versa.&nbsp;</p>



<h2 id="h-summary" class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">Here is a quick breakdown of the key distinction:&nbsp;</p>



<ul class="wp-block-list">
<li><strong>UART</strong>&nbsp;is the&nbsp;<strong>protocol logic</strong>&nbsp;inside the chip. It is typically used for on-board communication or direct debugging.&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li><strong>RS-232</strong>&nbsp;is the&nbsp;<strong>physical interface</strong>, most easily recognized by the standard&nbsp;DE9/DB9 connector. It is commonly employed to connect devices over external cables, using a transceiver to handle higher&nbsp;voltages and signal inversion.&nbsp;</li>
</ul>



<p class="wp-block-paragraph">Understanding where the logic ends and the physical layer begins helps design more robust systems and avoid compatibility issues.&nbsp;</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong><strong>Looking to solve complex embedded systems challenges?</strong></strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">DMC has extensive experience bridging the gap between low-level firmware and complex hardware integration. Learn more about our capabilities in <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">embedded development</a>.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/41558/uart-vs-rs-232-understanding-the-differences/">UART vs RS-232: Understanding the Differences</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Bridging the Embedded World and Siemens PLCs with an ESP32-P4 and Arduino </title>
		<link>https://static.dmcinfo.com/blog/41222/bridging-the-embedded-world-and-siemens-plcs-with-an-esp32-p4-and-arduino/</link>
		
		<dc:creator><![CDATA[DMC]]></dc:creator>
		<pubDate>Wed, 18 Feb 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<category><![CDATA[Manufacturing Automation & Intelligence]]></category>
		<category><![CDATA[Siemens PLC]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=41222</guid>

					<description><![CDATA[<p>Industrial-embedded integration matters today because modern factories increasingly rely on&#160;external&#160;embedded systems for real‑time monitoring&#160;and&#160;automation.&#160;Embedded systems are becoming companions&#160;to PLCs, unlocking capabilities that traditional control architectures alone&#160;may struggle to&#160;deliver while reducing system costs.&#160; To illustrate how&#160;the industrial and embedded&#160;worlds can work together,&#160;I&#160;built a simple demo that connects an ESP32-based device directly to a Siemens PLC using [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/41222/bridging-the-embedded-world-and-siemens-plcs-with-an-esp32-p4-and-arduino/">Bridging the Embedded World and Siemens PLCs with an ESP32-P4 and Arduino </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Industrial-embedded integration matters today because modern factories increasingly rely on&nbsp;external&nbsp;embedded systems for real‑time monitoring&nbsp;and&nbsp;automation.&nbsp;Embedded systems are becoming companions&nbsp;to PLCs, unlocking capabilities that traditional control architectures alone&nbsp;may struggle to&nbsp;deliver while reducing system costs.&nbsp;</p>



<p class="wp-block-paragraph">To illustrate how&nbsp;the industrial and embedded&nbsp;worlds can work together,&nbsp;I&nbsp;built a simple demo that connects an ESP32-based device directly to a Siemens PLC using the native&nbsp;Siemens&nbsp;S7 protocol.&nbsp;</p>



<p class="wp-block-paragraph">The result is&nbsp;an&nbsp;Ethernet-connected embedded system that reads PLC&nbsp;inputs&nbsp;in real time and uses that data to drive&nbsp;an&nbsp;RGB LED&nbsp;Pixels Strip:&nbsp;no gateways, no HMIs,&nbsp;and&nbsp;no middleware.</p>



<h2 id="h-demo-overview" class="wp-block-heading">Demo Overview</h2>



<p class="wp-block-paragraph">The&nbsp;demo&nbsp;is&nbsp;intentionally&nbsp;simple.&nbsp;I am using&nbsp;our PLC lab&nbsp;setup with&nbsp;a few&nbsp;switches&nbsp;and&nbsp;buttons&nbsp;connected to the PLC&nbsp;to&nbsp;control a standard RGB LED Pixels Strip&nbsp;connected to an ESP32-P4&nbsp;dev kit.&nbsp;The&nbsp;block diagram&nbsp;of the system is&nbsp;presented below.</p>



<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" width="1388" height="158" src="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-1.png" alt="" class="wp-image-41254" style="width:1200px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-1.png 1388w, https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-1-300x34.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-1-1024x117.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-1-768x87.png 768w" sizes="(max-width: 1388px) 100vw, 1388px" /></figure>



<p class="wp-block-paragraph">Here is a picture of the complete setup below:</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="420" height="810" src="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-2.png" alt="" class="wp-image-41255" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px;aspect-ratio:0.5185225598777893;object-fit:cover;width:300px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-2.png 420w, https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-2-156x300.png 156w" sizes="(max-width: 420px) 100vw, 420px" /></figure>



<h2 id="h-plc-nbsp-logic-and-configuration" class="wp-block-heading">PLC&nbsp;Logic and Configuration</h2>



<p class="wp-block-paragraph">There are&nbsp;two&nbsp;external switches and&nbsp;two&nbsp;buttons attached to the&nbsp;PLC.&nbsp;Each input is mapped to a location in the PLC data block. The PLC program updates this data block continuously based on the&nbsp;switches/buttons&#8217;&nbsp;state.&nbsp;</p>



<p class="wp-block-paragraph">The PLC exposes&nbsp;this&nbsp;data block&nbsp;that&nbsp;contains&nbsp;the state of four inputs:&nbsp;</p>



<ul class="wp-block-list">
<li>Two switches&nbsp;
<ul class="wp-block-list">
<li>DB1.DBX0.0: switch 1 &#8211; on/off&nbsp;</li>



<li>DB1.DBX0.1: switch 2 &#8211; chase effect on/off&nbsp;</li>
</ul>
</li>



<li>Two momentary push buttons&nbsp;
<ul class="wp-block-list">
<li>DB1.DBX0.2: push button 1 &#8211; color green&nbsp;</li>



<li>DB1.DBX0.3: push button 2 (normally closed) &#8211; color red&nbsp;</li>
</ul>
</li>
</ul>



<p class="wp-block-paragraph">The PLC&nbsp;should&nbsp;be&nbsp;configured to allow&nbsp;Siemens&nbsp;S7&nbsp;PUT/GET&nbsp;communication.&nbsp;S7&nbsp;is a native PLC protocol that allows external devices to read and write PLC memory areas over Ethernet. Unlike fieldbus protocols, S7 PUT/GET provides direct access to PLC data blocks, making it well-suited for lightweight integrations.&nbsp;</p>



<p class="wp-block-paragraph" style="padding-bottom:var(--wp--preset--spacing--30)">In this demo, the ESP32 acts as an S7 client, connecting directly to the PLC and&nbsp;periodically&nbsp;reading&nbsp;the&nbsp;data block&nbsp;DB1. No custom function blocks&nbsp;or&nbsp;other&nbsp;logic are&nbsp;required&nbsp;on the PLC side.&nbsp;For embedded devices, this protocol&nbsp;could&nbsp;provide&nbsp;a simple way&nbsp;to exchange data with a Siemens PLC while keeping the PLC logic minimal.</p>



<p class="wp-block-paragraph">There are a few&nbsp;important settings that&nbsp;need&nbsp;to be enabled on the PLC side&nbsp;for the S7 protocol to work properly:</p>



<p class="wp-block-paragraph"><strong>1.</strong> <strong>Disable optimized block access.</strong>&nbsp;The data block used for communication (DB1 in this demo) must have&nbsp;optimized&nbsp;block access disabled. This allows the&nbsp;S7 protocol&nbsp;to address&nbsp;data in the data block&nbsp;using absolute addresses such as DB1.DBX0.0&nbsp;</p>



<figure class="wp-block-image size-full is-resized has-custom-border" style="margin-bottom:var(--wp--preset--spacing--50)"><img decoding="async" width="985" height="651" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-3.jpg.png" alt="" class="wp-image-45081" style="border-width:1px;aspect-ratio:1.5130855509126897;object-fit:cover;width:745px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-3.jpg.png 985w, https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-3.jpg-300x198.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-3.jpg-768x508.png 768w" sizes="(max-width: 985px) 100vw, 985px" /></figure>



<p class="wp-block-paragraph"><strong>2.</strong> <strong>Enable PUT/GET communication.</strong>&nbsp;In the PLC&nbsp;Protection &amp; Security&nbsp;tab,&nbsp;enable PUT/GET communication.</p>



<figure class="wp-block-image size-full is-resized has-custom-border" style="margin-bottom:var(--wp--preset--spacing--60)"><img decoding="async" width="1047" height="430" src="https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-4.jpg.png" alt="S7 PLC interface" class="wp-image-45082" style="border-width:1px;aspect-ratio:2.426131716938471;width:745px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-4.jpg.png 1047w, https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-4.jpg-300x123.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-4.jpg-1024x421.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/02/esp32-p4-and-arduino-image-4.jpg-768x315.png 768w" sizes="(max-width: 1047px) 100vw, 1047px" /></figure>



<h2 id="h-esp32-p4-nbsp-firmware" class="wp-block-heading">ESP32-P4&nbsp;Firmware</h2>



<p class="wp-block-paragraph" id="h-esp32-p4-firmware">The ESP32-P4 is the latest addition to&nbsp;Espressif’s&nbsp;popular line of embedded controllers, designed for high-performance industrial and IoT applications. The official ESP32-P4 development kit provides a&nbsp;great&nbsp;platform for rapid prototyping.&nbsp;</p>



<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-4a4cdd03 wp-block-columns-is-layout-flex" style="padding-bottom:var(--wp--preset--spacing--40)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full has-custom-border"><img decoding="async" width="400" height="225" src="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-dev-kit-opening.gif" alt="" class="wp-image-41281" style="border-top-left-radius:20px;border-top-right-radius:20px;border-bottom-left-radius:20px;border-bottom-right-radius:20px"/></figure>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p class="wp-block-paragraph">For this demo, I selected the ESP32-P4 dev kit largely because it is new and it has native Ethernet support, allowing us to connect directly to the PLC without external adapters. This made setup straightforward, letting us focus on demonstrating seamless communication between embedded and industrial systems.</p>



<p class="wp-block-paragraph">&nbsp;&nbsp;The ESP32-P4 dev kit is configured in the Arduino IDE using Espressif&#8217;s official board support package. I am using largely default settings, but here is a screenshot of the dev kit configuration in Arduino IDE for reference.</p>
</div>
</div>



<div class="wp-block-columns are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-0e47273b wp-block-columns-is-layout-flex">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:66.66%">
<p class="wp-block-paragraph">To handle Siemens S7 communication on the ESP32,&nbsp;I am&nbsp;using&nbsp;<em>Settimino</em>, an&nbsp;open-source library.&nbsp;Settimino&nbsp;implements a lightweight S7 client that allows Arduino-compatible devices to communicate directly with Siemens PLCs over Ethernet/S7 protocol.&nbsp;In this demo, the library is used&nbsp;to&nbsp;periodically&nbsp;read&nbsp;a PLC data block and decode&nbsp;individual bits corresponding to physical switches and buttons.</p>



<p class="wp-block-paragraph">There is a&nbsp;commonly available&nbsp;“WS2812”&nbsp;RGB LED pixel strip&nbsp;connected&nbsp;to the ESP32 dev kit GPIO pin.&nbsp;The firmware changes the LED strip color and triggers a chase effect&nbsp;based on the state of the buttons/switches.</p>



<ul class="wp-block-list">
<li>ESP32-P4 runs an Arduino-based sketch that:</li>



<li>Initializes the Ethernet interface&nbsp;</li>



<li>Connects to the PLC over&nbsp;S7&nbsp;</li>



<li>Reads the data block&nbsp;DB1</li>



<li>Decodes individual bits corresponding to switches and buttons&nbsp;</li>



<li>Updates the&nbsp;RGB LED&nbsp;Pixel&nbsp;Strip based on the buttons/switches&nbsp;&nbsp;&nbsp;</li>
</ul>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image aligncenter size-full is-resized"><img decoding="async" width="300" height="445" src="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-6.png" alt="" class="wp-image-41260" style="aspect-ratio:0.6741675635130288;width:300px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-6.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/01/ESP32-P4-and-Arduino-6-202x300.png 202w" sizes="(max-width: 300px) 100vw, 300px" /></figure>
</div>
</div>



<p class="wp-block-paragraph">The ESP32 acts as a read-only S7 client in this demo, which keeps the PLC configuration simple and&nbsp;the&nbsp;data&nbsp;safe.&nbsp;This pattern is especially useful when&nbsp;the PLC should remain the system authority&nbsp;and the embedded device is purely a consumer,&nbsp;reading the data&nbsp;and not affecting the logic PLC is doing.&nbsp;Although the same approach can easily be extended to write data back to the PLC if required.&nbsp;</p>



<h2 id="h-takeaway-nbsp" class="wp-block-heading">Takeaway&nbsp;</h2>



<p class="wp-block-paragraph">This demo shows how a modern embedded platform like the ESP32 can integrate cleanly into a Siemens PLC environment using the S7 protocol&nbsp;without&nbsp;gateways, just straightforward Ethernet communication.&nbsp;</p>



<p class="wp-block-paragraph">For industrial products, this approach opens the door to&nbsp;smarter peripherals&nbsp;and&nbsp;better visualization&nbsp;at&nbsp;a&nbsp;potentially lower system cost.&nbsp;All while keeping the PLC program simple&nbsp;and maintainable.&nbsp;</p>



<p class="wp-block-paragraph">It is worth noting that Siemens S7 PUT/GET protocol is very insecure because it does not implement any encryption or authentication mechanism. So, it should only be used with caution and strictly on isolated networks to avoid unintended access to the PLC or other security risks.</p>



<p class="wp-block-paragraph">You can also <a href="https://youtube.com/shorts/jVgtWxaeaJE" type="link" id="https://youtube.com/shorts/jVgtWxaeaJE">watch a short video</a> overview of the demo.</p>



<p class="wp-block-paragraph">The full Arduino source code and PLC project are available on <a href="https://github.com/boriz/ESP32_to_SiemensS7" target="_blank" rel="noreferrer noopener">GitHub</a>.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Ready to connect the embedded and industrial worlds?</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">DMC can help develop solutions that combine <a href="https://static.dmcinfo.com/our-work/category/service/manufacturing-automation-and-intelligence/siemens-plc/" data-type="work_category" data-id="682">Siemens PLCs</a>, ESP32 platforms, and real-time industrial communications. Learn more about our our <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded</a> capabilities for your next project.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/41222/bridging-the-embedded-world-and-siemens-plcs-with-an-esp32-p4-and-arduino/">Bridging the Embedded World and Siemens PLCs with an ESP32-P4 and Arduino </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Resolving “No Space Left on Device” (ENOSPC) When Building Yocto in WSL2 </title>
		<link>https://static.dmcinfo.com/blog/41046/resolving-no-space-left-on-device-enospc-when-building-yocto-in-wsl2/</link>
		
		<dc:creator><![CDATA[Aleksey Mullin]]></dc:creator>
		<pubDate>Fri, 06 Feb 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=41046</guid>

					<description><![CDATA[<p>After spending hours building a Yocto Linux image in WSL2, it is discouraging to see it crash with a deceptively simple error with surprisingly complex root causes: This error often shows up late in the build, after you&#8217;ve already invested significant time, and it can recur even after cleaning up build files and artifacts. The [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/41046/resolving-no-space-left-on-device-enospc-when-building-yocto-in-wsl2/">Resolving “No Space Left on Device” (ENOSPC) When Building Yocto in WSL2 </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">After spending hours building a Yocto Linux image in WSL2, it is discouraging to see it crash with a deceptively simple error with surprisingly complex root causes:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">ShellScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly> No space left on device (errno = 28, ENOSPC) </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">No</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">space</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">left</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">on</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">device</span><span style="color: #D4D4D4"> (errno </span><span style="color: #CE9178">=</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">28</span><span style="color: #CE9178">,</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ENOSPC</span><span style="color: #D4D4D4">) </span></span></code></pre></div>



<p class="wp-block-paragraph">This error often shows up late in the build, after you&#8217;ve already invested significant time, and it can recur even after cleaning up build files and artifacts. The reason is that WSL storage has one extra layer compared to a typical Linux workstation, and Yocto is excellent at stressing it. </p>



<p class="wp-block-paragraph">This post walks through what ENOSPC really means in WSL2, why&nbsp;Yocto&nbsp;triggers it so reliably, how to diagnose the root cause, and the correct fixes that make your builds predictable again.&nbsp;</p>



<h2 id="h-what-enospc-actually-means-and-why-wsl2-makes-it-trickier" class="wp-block-heading">What ENOSPC Actually Means (and Why WSL2 Makes It Trickier)</h2>



<p class="wp-block-paragraph">On a traditional Linux machine,&nbsp;ENOSPC&nbsp;usually means one of two things:&nbsp;</p>



<ul class="wp-block-list">
<li>You’re&nbsp;out of disk space</li>



<li>You’re&nbsp;out of&nbsp;inodes&nbsp;(metadata entries used to track files)&nbsp;</li>
</ul>



<p class="wp-block-paragraph">In WSL2, there&#8217;s a third common cause: the Linux filesystem lives inside a <a href="https://learn.microsoft.com/en-us/windows/wsl/disk-space" target="_blank" rel="noreferrer noopener">virtual hard disk file</a> on Windows (typically <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color"><strong><em>ext4.vhdx</em></strong></mark>). So, you effectively have two storage:</p>



<ul class="wp-block-list">
<li>Inside WSL2 (Linux view) &#8211; An ext4 filesystem with “available space.”&nbsp;</li>
</ul>



<ul class="wp-block-list">
<li>On Windows (host view) &#8211;&nbsp;A&nbsp;VHDX file that must be able to expand on the host disk&nbsp;</li>
</ul>



<p class="wp-block-paragraph">If the VHDX can&#8217;t grow (because the Windows host drive is full, or because you&#8217;ve hit a configured limit), Linux reports ENOSPC even if you clearly remember deleting a bunch of files yesterday.</p>



<h2 id="h-why-nbsp-yocto-nbsp-builds-hit-the-wall-so-fast-nbsp" class="wp-block-heading">Why&nbsp;Yocto&nbsp;Builds Hit the Wall So Fast&nbsp;</h2>



<p class="wp-block-paragraph">Yocto&nbsp;produces a large amount of output and (more importantly) a massive number of small files. A typical build tree can easily exceed 100GB once you include build artifacts, shared state, downloads, logs, and repeated iterations.&nbsp;A representative footprint looks like&nbsp;this:&nbsp;</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><tbody><tr><td><strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">build/tmp</mark></em></strong></td><td>~ 90 GB</td></tr><tr><td><strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">sstate-cache</mark></em></strong></td><td>~ 9 GB</td></tr><tr><td><strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">downloads</mark></em></strong></td><td>~ 2 GB</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">Even a “single” build can push you into triple-digit GB usage quickly,&nbsp;especially with multiple machine configs, SDKs, images, or rebuild cycles.&nbsp;This is why even developers with large SSDs hit space issues faster than expected.&nbsp;</p>



<h2 id="h-why-you-nbsp-shouldn-t-nbsp-put-nbsp-yocto-nbsp-under-nbsp-mnt-nbsp" class="wp-block-heading">Why You&nbsp;Shouldn’t&nbsp;Put&nbsp;Yocto&nbsp;Under&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">/mnt/…</mark></em></strong>&nbsp;</h2>



<p class="wp-block-paragraph">It’s&nbsp;tempting to just place your&nbsp;Yocto&nbsp;workspace on a Windows host drive (<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">/mnt/c/yocto/…</mark></em></strong>), so it uses space on your physical SSD instead of the virtual hard disk file. But&nbsp;the&nbsp;Windows filesystem (NTFS) gets mounted into WLS via a translation layer. That cross-OS layer is convenient, but&nbsp;it’s&nbsp;not&nbsp;optimized&nbsp;for this style of compilations/builds that deal with&nbsp;hundreds of thousands of files.&nbsp;</p>



<p class="wp-block-paragraph">Microsoft’s guidance for these situations is&nbsp;<a href="https://learn.microsoft.com/en-us/windows/wsl/filesystems" target="_blank" rel="noreferrer noopener">straightforward</a>: for best performance, keep your build files&nbsp;inside the WSL filesystem. So, using the physical SSD&nbsp;won’t&nbsp;work in this case,&nbsp;and we should&nbsp;keep the&nbsp;Yocto&nbsp;tree under something like&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">~/yocto</mark></em></strong>, and not under&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">/mnt/c…</mark></em></strong>&nbsp;</p>



<h2 id="h-the-right-fix-clean-reclaim-and-put-the-vhdx-on-the-right-disk-nbsp" class="wp-block-heading">The Right Fix: Clean, Reclaim, and Put the VHDX on the Right Disk&nbsp;</h2>



<h3 id="h-step-1-clean-nbsp-yocto-nbsp-build-artifacts-inside-wsl-nbsp" class="wp-block-heading">Step 1: Clean&nbsp;Yocto&nbsp;Build Artifacts (Inside WSL)&nbsp;</h3>



<p class="wp-block-paragraph">If you need to get unblocked quickly, removing build outputs helps:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">ShellScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>rm -rf build/tmp/* 
rm -rf sstate-cache/* 
rm -rf downloads/* </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-rf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">build/tmp/</span><span style="color: #569CD6">*</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-rf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">sstate-cache/</span><span style="color: #569CD6">*</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">rm</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-rf</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">downloads/</span><span style="color: #569CD6">*</span><span style="color: #D4D4D4"> </span></span></code></pre></div>



<p class="wp-block-paragraph">This frees space&nbsp;inside&nbsp;ext4, which may be enough to complete a build.&nbsp;</p>



<h3 id="h-step-2-shrink-optimize-the-vhdx-so-windows-actually-gets-space-back" class="wp-block-heading">Step 2: Shrink/Optimize the VHDX (So Windows Actually Gets Space Back)</h3>



<p class="wp-block-paragraph">Deleting files inside ext4 does&nbsp;not&nbsp;necessarily reduce the physical size of&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">ext4.vhdx</mark></em></strong>.&nbsp;It’s&nbsp;common for the VHDX to grow during heavy workloads and&nbsp;<a href="https://github.com/microsoft/WSL/issues/4699" target="_blank" rel="noreferrer noopener">not automatically return that space to Windows</a>.&nbsp;</p>



<p class="wp-block-paragraph">To reclaim space on the Windows host, shut down WSL, then&nbsp;optimize&nbsp;the VHDX from PowerShell:&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">ShellScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>wsl --shutdown 
Optimize-VHD -Path "D:\WSL\Ubuntu\ext4.vhdx" -Mode Full </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--shutdown</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">Optimize-VHD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-Path</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;D:\WSL\Ubuntu\ext4.vhdx&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-Mode</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Full</span><span style="color: #D4D4D4"> </span></span></code></pre></div>



<p class="wp-block-paragraph">This approach is commonly recommended for&nbsp;<a href="https://learn.microsoft.com/en-us/answers/questions/4006845/reduce-disk-space-consumption-for-wsl" target="_blank" rel="noreferrer noopener">compacting WSL VHDX files after cleanup</a>.</p>



<p class="wp-block-paragraph">Note:&nbsp;Optimize-VHD&nbsp;requires&nbsp;the Hyper-V VHD tooling (available on many Windows editions). If you&nbsp;don’t&nbsp;have it, you may need to enable the&nbsp;appropriate Windows features.&nbsp;</p>



<h3 id="h-step-3-move-the-wsl-distribution-to-a-larger-drive-nbsp" class="wp-block-heading">Step 3: Move the WSL Distribution to a Larger Drive&nbsp;</h3>



<p class="wp-block-paragraph">If your&nbsp;Yocto&nbsp;workflow is a long-term need, the most robust fix is to ensure the distro (and therefore the VHDX&nbsp;file) lives on a drive with plenty of headroom.&nbsp;</p>



<h4 id="h-method-nbsp-0-nbsp-why-moving-ubuntu-in-windows-settings-nbsp-doesn-t-nbsp-work-nbsp" class="wp-block-heading">Method&nbsp;0:&nbsp;Why “Moving Ubuntu” in Windows Settings&nbsp;Doesn’t&nbsp;Work&nbsp;</h4>



<p class="wp-block-paragraph">Windows has an&nbsp;app setting that&nbsp;appears to “move”&nbsp;Ubuntu. In practice, this often moves the&nbsp;application wrapper, not necessarily the underlying storage you care about&nbsp;(VHDX file).&nbsp;If you need more space, you typically need to&nbsp;move the&nbsp;distribution’s&nbsp;VHDX&nbsp;(or&nbsp;relocate&nbsp;the distro) to a larger drive using WSL-supported methods (covered below).&nbsp;</p>



<h4 id="h-method-a-export-import-reliable-and-widely-supported" class="wp-block-heading">Method A: Export / Import (Reliable and Widely Supported)</h4>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">ShellScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>wsl --export Ubuntu D:\backup\ubuntu.tar 
wsl --unregister Ubuntu 
wsl --import Ubuntu D:\WSL\Ubuntu D:\backup\ubuntu.tar --version 2 </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--export</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Ubuntu</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">D:</span><span style="color: #D7BA7D">\b</span><span style="color: #CE9178">ackup</span><span style="color: #D7BA7D">\u</span><span style="color: #CE9178">buntu.tar</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--unregister</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Ubuntu</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--import</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Ubuntu</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">D:</span><span style="color: #D7BA7D">\W</span><span style="color: #CE9178">SL</span><span style="color: #D7BA7D">\U</span><span style="color: #CE9178">buntu</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">D:</span><span style="color: #D7BA7D">\b</span><span style="color: #CE9178">ackup</span><span style="color: #D7BA7D">\u</span><span style="color: #CE9178">buntu.tar</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--version</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> </span></span></code></pre></div>



<p class="wp-block-paragraph">This moves the distro storage to&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">D:\WSL\Ubuntu</mark></em></strong>&nbsp;</p>



<h4 id="h-method-b-nbsp-wsl-nbsp-manage-move-nbsp-newer-simpler-nbsp" class="wp-block-heading">Method B:&nbsp;<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color"><strong><em>wsl&nbsp;&#8211;manage &#8211;move</em></strong></mark>&nbsp;(Newer, Simpler)&nbsp;</h4>



<p class="wp-block-paragraph">Newer WSL releases include a built-in move command:&nbsp;</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">ShellScript</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>wsl --update 
wsl --manage Ubuntu --move D:\WSL\Ubuntu  </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--update</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #DCDCAA">wsl</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--manage</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Ubuntu</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">--move</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">D:</span><span style="color: #D7BA7D">\W</span><span style="color: #CE9178">SL</span><span style="color: #D7BA7D">\U</span><span style="color: #CE9178">buntu</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178"> </span></span></code></pre></div>



<p class="wp-block-paragraph">This is supported in WSL versions that include the&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">&#8211;move</mark></em></strong>&nbsp;option&nbsp;and is often the cleanest approach when available.&nbsp;</p>



<h2 id="h-conclusion-nbsp" class="wp-block-heading">Conclusion&nbsp;</h2>



<p class="wp-block-paragraph">In WSL2, “No space left on device” often&nbsp;isn’t&nbsp;just about what&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">df</mark></em></strong>&nbsp;shows inside Linux.&nbsp;It’s about how WSL stores Linux data in a Windows-hosted VHDX that expands over time and may not automatically shrink.&nbsp;</p>



<p class="wp-block-paragraph">The most reliable path to predictable&nbsp;Yocto&nbsp;builds is:&nbsp;</p>



<ol class="wp-block-list">
<li>Yocto&nbsp;is not a 20 GB project. Budget&nbsp;hundreds&nbsp;of GB.&nbsp;</li>



<li>Keep&nbsp;Yocto&nbsp;workspaces on ext4 inside WSL (not&nbsp;<strong><em><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-custom-medium-blue-color">/mnt/*</mark></em></strong>).</li>



<li>Clean build artifacts when needed.</li>



<li>Compact the VHDX after cleanup.</li>



<li>Move the VHDL file to a larger drive.</li>
</ol>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step">Overcome <em>WSL2</em> and <em>Yocto Build</em> Hurdles with DMC.</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">DMC can help you optimize your <em>WSL2</em> or <em>Yocto</em> setup and fix any challenges for your <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded Development</a> needs.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/41046/resolving-no-space-left-on-device-enospc-when-building-yocto-in-wsl2/">Resolving “No Space Left on Device” (ENOSPC) When Building Yocto in WSL2 </a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Arduino Nano R4 CAN Protocol</title>
		<link>https://static.dmcinfo.com/blog/40485/arduino-nano-r4-can-protocol/</link>
		
		<dc:creator><![CDATA[Thomas Panek Gonzalez]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 13:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=40485</guid>

					<description><![CDATA[<p>This past summer, Arduino released a new version within their popular microcontroller series, the Nano R4. In a previous article I wrote about the new USB HID functionality that was added in the release. In this article I would like to focus on the addition of the CAN protocol being native to the Arduino Nano [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/40485/arduino-nano-r4-can-protocol/">Arduino Nano R4 CAN Protocol</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">This past summer, Arduino released a new version within their popular microcontroller series, the Nano R4. In <a href="https://static.dmcinfo.com/blog/37479/arduino-nano-r4-usb-hid-functionality-and-first-impressions/">a previous article</a> I wrote about the new USB HID functionality that was added in the release. In this article I would like to focus on the addition of the CAN protocol being native to the Arduino Nano R4.</p>



<h2 id="h-can-protocol-electrical" class="wp-block-heading">CAN Protocol &#8211; Electrical</h2>



<p class="wp-block-paragraph">The CAN (Controller Area Network) Protocol is a serial bus interface used to connect multiple devices in a <strong>Network. </strong>The devices all connect to a common <strong>Bus</strong> and share a twisted pair of wires called <strong>CAN High</strong> and <strong>CAN Low</strong>. The protocol requires 3 conductors to operate: <strong>CAN H</strong>, <strong>CAN L</strong>, and Ground. These CAN lines are opposites of each other. When the CAN lines are digital low, both <strong>CAN H</strong> and <strong>CAN L</strong> are at the same voltage. When the bus goes digital high, the line’s voltages go in opposite directions. For example, if they are digital low at a voltage of 2.5V, then at digital high, <strong>CAN H</strong> may be at 3.5V while <strong>CAN L</strong> would be at 1.5V. The voltages are equidistant from the digital low voltage which is called <strong>differential signaling. </strong>The benefits for differential signaling are that they minimize EMI (Electromagnetic Interference), allow long runs of wire, and high throughput. CAN is most used in vehicular communications and industrial automation.</p>



<h2 id="h-how-can-works-logical-protocol" class="wp-block-heading">How CAN Works – Logical Protocol</h2>



<p class="wp-block-paragraph">CAN in its simplest explanation can be thought of a group call full of people attempting to all talk to each other. Someone initiates a conversation by stating their ID and the ID of whom they need to communicate with. This allows the two to communicate effectively, all while sharing space with others. If two speakers attempt to communicate at the same time, the ID that is lower numerically is allowed to communicate first, the other follows unless a speaker with an ID that is lower attempts to speak. The speakers here are the devices (sensors, MCUs, etc.) and the shared space is the wires/bus.</p>



<h2 id="h-what-the-nano-r4-can-now-do" class="wp-block-heading">What the Nano R4 CAN Now Do</h2>



<p class="wp-block-paragraph">This iteration of the Arduino Nano now has the R7FA4M1AB3CFM#HA0 32-bit MCU from <strong>Renesas</strong> which has a CAN controller packaged into it. The use of R4’s CAN peripheral <strong>requires an external CAN transceiver</strong>&nbsp;to work with a CAN bus. Arduino recommends transceivers such as the SN65HVD230 from Texas Instruments or the MCP2561 from Microchip. For my setup I used a TJA1050T made by NXP USA.</p>



<h2 id="h-example-code" class="wp-block-heading">Example Code</h2>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:16px 0 0 16px;width:100%;text-align:left;background-color:#1e1e1e"><span style="background:#c7c7c7;padding:0.3rem 0.5rem 0.2rem;border-radius:1rem;font-size:0.8em;line-height:1;height:1.25rem;text-align:center;display:inline-flex;align-items:center;justify-content:center;color:#1e1e1e">C++</span></span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>#include &lt;Arduino_CAN.h>
//This Code Honks the horn of a Tesla when a button is pressed on D6
#define BUTTON_PIN D6
#define HONK_TIME_MS 50
#define CAN_ID_HONK 0x273
bool lastButtonState = HIGH;

void setup() {
  // Serial is optional; do not block startup
  Serial.begin(115200);

  pinMode(BUTTON_PIN, INPUT_PULLUP); // button wired D6 → GND

  if (!CAN.begin(CanBitRate::BR_500k)) //Check if CAN started up fine
  {
    while (1); // hard fail
  }
}

void loop() {
  bool buttonState = digitalRead(BUTTON_PIN); //Read button

  if (buttonState == LOW &amp;&amp; lastButtonState == HIGH)   // Detect button press and release
  {
    // Build CAN frame
    CanMsg hornMsg;
    hornMsg.id = CAN_ID_HONK; // ID273UI_vehicleControl
    hornMsg.data_length = 8;

    // Zero the 8 bytes
    for (int i = 0; i &lt; 8; i++) {
      hornMsg.data&#091;i&#093; = 0;
    }

    // Bit 61 → byte 7, bit 5
    hornMsg.data&#091;7&#093; = 0x20;

    // Honk ON
    CAN.write(hornMsg);

    delay(HONK_TIME_MS);//Horn honks for 

    // Honk OFF
    hornMsg.data&#091;7&#093; = 0x00;
    CAN.write(hornMsg);
    Serial.println("Horn triggered"); 
  }
  lastButtonState = buttonState; //Set previous button state
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M16.5 8.25V6a2.25 2.25 0 00-2.25-2.25H6A2.25 2.25 0 003.75 6v8.25A2.25 2.25 0 006 16.5h2.25m8.25-8.25H18a2.25 2.25 0 012.25 2.25V18A2.25 2.25 0 0118 20.25h-7.5A2.25 2.25 0 018.25 18v-1.5m8.25-8.25h-6a2.25 2.25 0 00-2.25 2.25v6"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #C586C0">#include</span><span style="color: #569CD6"> </span><span style="color: #CE9178">&lt;Arduino_CAN.h&gt;</span></span>
<span class="line"><span style="color: #6A9955">//This Code Honks the horn of a Tesla when a button is pressed on D6</span></span>
<span class="line"><span style="color: #C586C0">#define</span><span style="color: #569CD6"> BUTTON_PIN D6</span></span>
<span class="line"><span style="color: #C586C0">#define</span><span style="color: #569CD6"> HONK_TIME_MS 50</span></span>
<span class="line"><span style="color: #C586C0">#define</span><span style="color: #569CD6"> CAN_ID_HONK 0x273</span></span>
<span class="line"><span style="color: #569CD6">bool</span><span style="color: #D4D4D4"> lastButtonState = HIGH;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">setup</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #6A9955">  // Serial is optional; do not block startup</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #9CDCFE">Serial</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">begin</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">115200</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #DCDCAA">pinMode</span><span style="color: #D4D4D4">(BUTTON_PIN, INPUT_PULLUP);</span><span style="color: #6A9955"> // button wired D6 → GND</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (!</span><span style="color: #9CDCFE">CAN</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">begin</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">CanBitRate</span><span style="color: #D4D4D4">::BR_500k))</span><span style="color: #6A9955"> //Check if CAN started up fine</span></span>
<span class="line"><span style="color: #D4D4D4">  {</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">while</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">);</span><span style="color: #6A9955"> // hard fail</span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">loop</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">bool</span><span style="color: #D4D4D4"> buttonState = </span><span style="color: #DCDCAA">digitalRead</span><span style="color: #D4D4D4">(BUTTON_PIN);</span><span style="color: #6A9955"> //Read button</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (buttonState == LOW &amp;&amp; lastButtonState == HIGH)</span><span style="color: #6A9955">   // Detect button press and release</span></span>
<span class="line"><span style="color: #D4D4D4">  {</span></span>
<span class="line"><span style="color: #6A9955">    // Build CAN frame</span></span>
<span class="line"><span style="color: #D4D4D4">    CanMsg hornMsg;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">hornMsg</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">id</span><span style="color: #D4D4D4"> = CAN_ID_HONK;</span><span style="color: #6A9955"> // ID273UI_vehicleControl</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">hornMsg</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data_length</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">8</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    // Zero the 8 bytes</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">int</span><span style="color: #D4D4D4"> i = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; i &lt; </span><span style="color: #B5CEA8">8</span><span style="color: #D4D4D4">; i++) {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">hornMsg</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">&#091;i&#093; = </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    // Bit 61 → byte 7, bit 5</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">hornMsg</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">&#091;</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">&#093; = </span><span style="color: #B5CEA8">0x20</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    // Honk ON</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">CAN</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">write</span><span style="color: #D4D4D4">(hornMsg);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">delay</span><span style="color: #D4D4D4">(HONK_TIME_MS);</span><span style="color: #6A9955">//Horn honks for </span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">    // Honk OFF</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">hornMsg</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">data</span><span style="color: #D4D4D4">&#091;</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">&#093; = </span><span style="color: #B5CEA8">0x00</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">CAN</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">write</span><span style="color: #D4D4D4">(hornMsg);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">Serial</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">println</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Horn triggered&quot;</span><span style="color: #D4D4D4">); </span></span>
<span class="line"><span style="color: #D4D4D4">  }</span></span>
<span class="line"><span style="color: #D4D4D4">  lastButtonState = buttonState;</span><span style="color: #6A9955"> //Set previous button state</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<h2 id="h-setup" class="wp-block-heading">Setup</h2>



<p class="wp-block-paragraph">To use the code shown above, one needs access to the CAN network in their Tesla vehicle. In the car used for this article, a 2021 Tesla Model Y Long Range, the CAN bus was found behind the center console, near the floor. A plastic cover needed to be pried off, and a splicer was purchased to connect in series. USB-C power was supplying the Nano R4.&nbsp;The provided code waits for a button to be pressed and released, connected to D6 and GND, and from there a data packet sends the honk horn bit for 50ms before setting it back to off. The idea is if the driver is hesitant to honk, the passenger can take some initiative. Below is the wiring needed for the CAN buses to work:</p>



<ul class="wp-block-list">
<li>Arduino GND to CAN Transceiver GND to Pin 5</li>



<li>Arduino 5V to CAN Transceiver PWR</li>



<li>CAN Transceiver CAN HIGH to Pin 6</li>



<li>CAN Transceiver CAN LOW to Pin 14</li>



<li>Arduino CAN RX to CAN Transceiver CAN RX</li>



<li>Arduino CAN TX to CAN Transceiver CAN TX</li>
</ul>



<figure class="wp-block-image size-large is-resized"><img decoding="async" width="1024" height="576" src="https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-1024x576.png" alt="CAN BUS Wires" class="wp-image-40626" style="width:1175px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-1024x576.png 1024w, https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-300x169.png 300w, https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-768x432.png 768w, https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-1536x863.png 1536w, https://static.dmcinfo.com/wp-content/uploads/2026/01/can-bus-wires.drawio-1-2048x1151.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h2 id="h-can-bus-demo" class="wp-block-heading">CAN BUS Demo</h2>



<figure class="wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler"><div class="wp-block-embed__wrapper">
<div style="width: 640px;" class="wp-video"><video class="wp-video-shortcode" id="video-40485-1" width="640" height="360" preload="metadata" controls="controls"><source type="video/mp4" src="https://static.dmcinfo.com/wp-content/uploads/2025/12/25.12.17-CAN-Demo-Vid.mp4?_=1" /><a href="https://static.dmcinfo.com/wp-content/uploads/2025/12/25.12.17-CAN-Demo-Vid.mp4">https://static.dmcinfo.com/wp-content/uploads/2025/12/25.12.17-CAN-Demo-Vid.mp4</a></video></div>
</div></figure>



<h2 id="h-conclusion" class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">In my sample code, I was able to control one of thousands of settings within my vehicle through the CAN bus. Some other examples could be starting seat heat on various seats, opening and closing the trunk, or turning on the wipers, with thousands of other controls for the vehicle. Some of these can damage the car and tinkerers should be careful not to damage the car with the messages being sent to it, especially whilst driving. The ones chosen here are generally low risk. Though overall CAN is a very robust protocol and can be used in many applications.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>Need a partner who can help develop reliable CAN-based embedded solutions</strong>?</h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Learn more about DMC&#8217;s capabilities in <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/arduino-programming/" data-type="page" data-id="671">Arduino Nano R4</a> CAN Bus Communication, including hardware setup, transceivers, and example code for your <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded</a> systems.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://static.dmcinfo.com/blog/40485/arduino-nano-r4-can-protocol/">Arduino Nano R4 CAN Protocol</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		<enclosure url="https://static.dmcinfo.com/wp-content/uploads/2025/12/25.12.17-CAN-Demo-Vid.mp4" length="14936136" type="video/mp4" />

			</item>
		<item>
		<title>Integrating EtherCAT into Custom Applications</title>
		<link>https://static.dmcinfo.com/blog/40513/integrating-ethercat-into-custom-applications/</link>
		
		<dc:creator><![CDATA[Jim Smith]]></dc:creator>
		<pubDate>Tue, 13 Jan 2026 01:00:00 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=40513</guid>

					<description><![CDATA[<p>Applications such as advanced industrial control systems and robotics require precise motion control, synchronized data sampling, and fast deterministic field buses. Traditional Ethernet TCP/IP, CAN or Modbus-based systems lack the speed, coordination, and scalability required for these applications. That’s where EtherCAT comes in. Originally developed by Beckhoff, EtherCAT (Ethernet for Control Automation Technology) has become [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/40513/integrating-ethercat-into-custom-applications/">Integrating EtherCAT into Custom Applications</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Applications such as advanced industrial control systems and robotics require precise motion control, synchronized data sampling, and fast deterministic field buses. Traditional Ethernet TCP/IP, CAN or Modbus-based systems lack the speed, coordination, and scalability required for these applications.</p>



<p class="wp-block-paragraph">That’s where EtherCAT comes in.</p>



<p class="wp-block-paragraph">Originally developed by Beckhoff, EtherCAT (Ethernet for Control Automation Technology) has become one of the most popular real-time industrial Ethernet standards. It’s fast, reliable, and highly scalable &#8211; making it an excellent fit for applications where timing and performance are critical.</p>



<h2 id="h-why-ethercat-fits-high-performance-embedded-applications" class="wp-block-heading">Why EtherCAT Fits High-Performance Embedded Applications</h2>



<p class="wp-block-paragraph">EtherCAT’s efficiency comes from how it moves data. EtherCAT masters can use standard off the shelf ethernet hardware, and they transmit standard Ethernet frames with the EtherCAT EtherType Identifier. The entire EtherCAT data payload (EtherCAT Telegram) for the entire network is embedded into the Ethernet payload. Every device on the network is daisy-chained together, and each device allows the entire Ethernet frame to pass through it, imparting minimal delay on the entire message. Each device will read out its section (Datagram) of the EtherCAT Telegram and insert the data that it is sending back to the master. This all happens on the fly as the frame is effectively passing through the device. The last device on the network will then turn the frame around and send it back up to the master. This is possible because of the full-duplex nature of Ethernet.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="601" height="174" src="https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-frame.png" alt="EtherCAT Frame" class="wp-image-40516" style="width:615px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-frame.png 601w, https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-frame-300x87.png 300w" sizes="(max-width: 601px) 100vw, 601px" /></figure>



<p class="wp-block-paragraph">The following image shows how an EtherCAT frame might traverse through a network. The master transmits the frame, and each device will extract data in the Datagram addressed to it and insert its data on the fly into the Datagram. In this example very simple addressing is used as an example, most of the time such positional addressing is only used at network boot-up/discovery. Data not addressed to the slave is passed through the network until it reaches the end of the network, where the last slave sends it back to the master.</p>



<figure class="wp-block-image size-full is-resized"><img decoding="async" width="624" height="162" src="https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-master.png" alt="EtherCAT Master" class="wp-image-40518" style="width:632px;height:auto" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-master.png 624w, https://static.dmcinfo.com/wp-content/uploads/2025/12/ethercat-master-300x78.png 300w" sizes="(max-width: 624px) 100vw, 624px" /></figure>



<p class="wp-block-paragraph">This “processing on the fly” approach eliminates most of the traditional Ethernet delays caused by the need to address each device individually and enables cycle times in the tens of microseconds, with minimal jitter.</p>



<p class="wp-block-paragraph">The protocol can also implement a feature called Distributed Clocks (DC), where the master can measure time, it takes for each device to receive and respond to a sync message, then provide each device with an offset to ensure all devices are synchronized within ~100ns of each other. This allows each EtherCAT controller to create a synchronization event for each device on the network within 100ns of each other.</p>



<p class="wp-block-paragraph">For custom devices, that means:</p>



<ul class="wp-block-list">
<li>Deterministic timing for motion control and automation.</li>



<li>Relatively low resource overhead compared to the capabilities, since much of the protocol runs in hardware.</li>



<li>Scalability, from a single board with a few I/O channels to complex multi-axis systems.</li>
</ul>



<h2 id="h-types-of-ethercat-devices" class="wp-block-heading">Types of EtherCAT Devices</h2>



<p class="wp-block-paragraph">There are two types of EtherCAT devices that can be implemented:</p>



<h3 id="h-1-ethercat-masters" class="wp-block-heading">1. EtherCAT Masters</h3>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">EtherCAT masters are usually run on controllers or embedded PCs that coordinate the network, process data and issue commands to each device on the network. In industrial applications (i.e.&nbsp;<a target="_blank" href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/" rel="noreferrer noopener">Industrial Automation</a>) a master is usually an Industrial PC or&nbsp;<a target="_blank" href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/plc-programming/" rel="noreferrer noopener">PLC</a>&nbsp;running&nbsp;<a target="_blank" href="https://static.dmcinfo.com/services/manufacturing-automation-and-intelligence/hmi-and-scada-programming/twincat-3-hmi-programming/" rel="noreferrer noopener">TwinCAT</a>.</p>
</blockquote>



<p class="wp-block-paragraph">Open-source stacks like Simple Open EtherCAT Master (SOEM) provide a lightweight, C-based master that runs on Linux or RTOS platforms. This can be a great option for small applications, such as a dedicated robot or lightweight real-time control system for highly integrated applications. These stacks typically work on commonly available hardware that supports standard Ethernet-based communication. This is because the master does not require any specialized hardware, it just needs raw access to the underlying Ethernet frames.</p>



<h3 id="h-2-ethercat-slaves-subdevice" class="wp-block-heading">2. EtherCAT Slaves/SubDevice</h3>



<p class="wp-block-paragraph">Used when building custom EtherCAT-enabled devices like sensors, actuators, modular I/O, or motor/servo controllers.</p>



<p class="wp-block-paragraph">Beckhoff’s Slave Stack Code (SSC) tool generates a firmware library that implements EtherCAT communication layer on your supported hardware. The &#8220;processing on the fly&#8221; of EtherCAT is really implemented in the EtherCAT slave controller hardware and not in software. So, the slaves/subdevices require specialized hardware to interface with the EtherCAT network properly.</p>



<p class="wp-block-paragraph">This specialized hardware can take the form of a traditional microcontroller (i.e. STM32, TI C2000&#8230;) paired with an EtherCAT Slave Controller IC (ESC) like the LAN9252, or Beckhoff ET1100. Alternatively, some specialized microcontrollers, such as the TI TMS320F28388 or Infineon XMC4800 series, integrate the EtherCAT controller as a peripheral on chip.</p>



<p class="wp-block-paragraph">In both cases, success depends on selecting compatible hardware and providing a real-time-capable software environment. For masters, that often means using a deterministic OS (e.g., PREEMPT_RT Linux or FreeRTOS). For slaves, it’s ensuring your MCU and ESC can handle EtherCAT’s timing and synchronization.</p>



<h3 id="h-explore-further-reading" class="wp-block-heading">Explore Further Reading</h3>



<ul class="wp-block-list">
<li><a href="https://www.ethercat.org/">EtherCAT Technology Group</a></li>



<li><a href="https://github.com/OpenEtherCATsociety/SOEM">SOME GitHub Repository</a></li>



<li><a href="https://www.ethercat.org/en/downloads/downloads_01DCC32A10294F2EA866F7E46FB0285F.htm">Beckhoff Slave Stack Code (SSC)</a></li>



<li><a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/">DMC Embedded Development Services</a></li>
</ul>



<h2 id="h-conclusion" class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">EtherCAT brings industrial-grade speed and synchronization to embedded systems without requiring massive computing resources. With the right combination of hardware, stack software, and validation tools, engineers can build compact, deterministic systems that rival full-scale automation controllers in responsiveness and reliability.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>High-performance automation systems with support from DMC&#8217;s EtherCAT experts.</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">Discover DMC&#8217;s <a href="https://static.dmcinfo.com/our-work/real-time-ethercat-motion-control-with-ni-crio-and-embedded-ui/" data-type="our_work" data-id="14598">EtherCAT</a> integration capabilities for your custom <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded</a> applications for real-time motion control, synchronized data acquisition, and industrial automation.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/40513/integrating-ethercat-into-custom-applications/">Integrating EtherCAT into Custom Applications</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Delay Calculator for RC Voltage Divider</title>
		<link>https://static.dmcinfo.com/blog/40375/delay-calculator-for-rc-voltage-divider/</link>
		
		<dc:creator><![CDATA[Aleksandr Sorokin]]></dc:creator>
		<pubDate>Tue, 06 Jan 2026 17:23:18 +0000</pubDate>
				<category><![CDATA[Embedded Development & Programming]]></category>
		<guid isPermaLink="false">https://static.dmcinfo.com/?p=40375</guid>

					<description><![CDATA[<p>Voltage dividers are one of the simplest and most widely used circuits in electronics. Their behavior can be extended by adding a capacitor, introducing a time-dependent response. This allows controlled startup delays and ensures that downstream circuits receive power only after the capacitor reaches a required voltage level. A capacitor added to a classic voltage [&#8230;]</p>
<p>The post <a href="https://static.dmcinfo.com/blog/40375/delay-calculator-for-rc-voltage-divider/">Delay Calculator for RC Voltage Divider</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Voltage dividers are one of the simplest and most widely used circuits in electronics. Their behavior can be extended by adding a capacitor, introducing a time-dependent response. This allows controlled startup delays and ensures that downstream circuits receive power only after the capacitor reaches a required voltage level.</p>



<p class="wp-block-paragraph">A capacitor added to a classic voltage divider introduces a predictable delay before enabling another component, such as a DC-DC converter or logic device. The RC Voltage Divider Delay Calculator determines key timing parameters based on the divider components, input voltage, and the required threshold voltage.</p>



<figure class="wp-block-image size-full is-resized has-custom-border"><img decoding="async" width="317" height="215" src="https://static.dmcinfo.com/wp-content/uploads/2025/12/voltage-divider.png" alt="voltage divider" class="wp-image-40376" style="border-radius:20px;width:300px" srcset="https://static.dmcinfo.com/wp-content/uploads/2025/12/voltage-divider.png 317w, https://static.dmcinfo.com/wp-content/uploads/2025/12/voltage-divider-300x203.png 300w" sizes="(max-width: 317px) 100vw, 317px" /></figure>



<div style="padding: 10px; "> 
  <div style="width: 100%;">
    <h2>RC Time Delay Calculator</h2>
  </div>
  
  <div style="width: 100%;">
    <div style="width: 50%; float:left"> 
      <div>
        <label for="Vin">Input Voltage (Vin, V):</label>
        <input type="number" id="Vin" value="5" min="0.1" step="0.1" style="width:100px;">
      </div>
      <div>
        <label for="R1">Resistor R1 (kΩ):</label>
        <input type="number" id="R1" value="10" min="0.001" step="0.001" style="width:100px;">
      </div>

      <div>
        <label for="R2">Resistor R2 (kΩ):</label>
        <input type="number" id="R2" value="10" min="0.001" step="0.001" style="width:100px;">
      </div>
      <div>
        <label for="C">Capacitance (µF):</label>
        <input type="number" id="C" value="1" min="0.000001" step="0.000001" style="width:100px;">
      </div>
      <div>
        <label for="Vt">Threshold Voltage (V_threshold, V):</label>
        <input type="number" id="Vt" value="1" min="0.1" step="0.1" style="width:100px;">
      </div>

      <div style="padding:10px 0;">
        <button id="calcBtn">Calculate</button>
      </div>

      <div>
        <br>
        <div>Final capacitor voltage (V_final): <b><span id="vfinal">—</span></b></div>
        <div>Time to threshold (t_enable): <b><span id="ten">—</span></b></div>
        <div>Time to 99% of V_final: <b><span id="tfull">—</span></b></div>
      </div>

    </div>

    <div style="width: 50%; float:right">
      <canvas id="graph" width="500" height="300" style="border:1px solid black;"></canvas>
    </div>
    
  </div>

</div>

<script>
function clearGraph() {
  const c = document.getElementById("graph");
  const ctx = c.getContext("2d");
  ctx.clearRect(0, 0, c.width, c.height);
}
 
function calculate() {
  clearGraph();
 
  const Vin = parseFloat(document.getElementById("Vin").value);
  const R1  = parseFloat(document.getElementById("R1").value) * 1000; // kΩ -> Ω
  const R2  = parseFloat(document.getElementById("R2").value) * 1000;
  const C   = parseFloat(document.getElementById("C").value)  / 1e6;  // µF -> F
  const Vt  = parseFloat(document.getElementById("Vt").value);
 
  if (!(Vin > 0 && R1 > 0 && R2 > 0 && C > 0 && Vt > 0)) {
    alert("Please enter valid positive values for all fields.");
    return;
  }
 
  // Final divider / capacitor voltage
  const V_final = Vin * (R2 / (R1 + R2));
 
  if (Vt >= V_final) {
    alert("Threshold voltage must be less than the final capacitor voltage (V_final).");
    return;
  }
 
  // Thevenin resistance and time constant
  const R_th = (R1 * R2) / (R1 + R2);
  const tau  = R_th * C;
 
  // Times in ms
  const t99  = 4.6 * tau * 1000;                          // 99% of V_final
  const ten  = -tau * Math.log(1 - Vt / V_final) * 1000;  // enable time
 
  document.getElementById("vfinal").textContent = V_final.toFixed(3) + " V";
  document.getElementById("ten").textContent    = ten.toFixed(2) + " ms";
  document.getElementById("tfull").textContent  = t99.toFixed(2) + " ms";
 
  drawGraph(V_final, tau, Vt);
}
 
function drawGraph(V_final, tau, Vt) {
  const c = document.getElementById("graph");
  const ctx = c.getContext("2d");
 
  const W = c.width;
  const H = c.height;
 
  // Margins for labels and axes
  const left   = 55;
  const right  = 15;
  const top    = 15;
  const bottom = 40;
 
  const plotW = W - left - right;
  const plotH = H - top - bottom;
 
  const tmax = 5 * tau * 1000;   // 5τ, ms
  const step = tmax / plotW;
 
  ctx.clearRect(0, 0, W, H);
  ctx.font = "12px Arial";
 
  // Background
  ctx.fillStyle = "white";
  ctx.fillRect(0, 0, W, H);
 
  // Grid + time labels (X axis)
  ctx.strokeStyle = "#ddd";
  ctx.lineWidth = 1;
  ctx.fillStyle = "black";
 
  const xDivs = 5;
  for (let i = 0; i <= xDivs; i++) {
    const x = left + (plotW / xDivs) * i;
    ctx.beginPath();
    ctx.moveTo(x, top);
    ctx.lineTo(x, top + plotH);
    ctx.stroke();
 
    const tMs = (tmax / xDivs) * i;
    ctx.fillText(tMs.toFixed(0) + " ms", x - 15, top + plotH + 15);
  }
 
  // Grid + voltage labels (Y axis)
  const yDivs = 5;
  for (let i = 0; i <= yDivs; i++) {
    const y = top + (plotH / yDivs) * i;
    ctx.beginPath();
    ctx.moveTo(left, y);
    ctx.lineTo(left + plotW, y);
    ctx.stroke();
 
    const V = V_final * (1 - i / yDivs);
    ctx.fillText(V.toFixed(1) + " V", left + 5, y + 4);
  }
 
  // Threshold line
  const yVt = top + plotH - (Vt / V_final) * plotH;
  ctx.strokeStyle = "red";
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.moveTo(left, yVt);
  ctx.lineTo(left + plotW, yVt);
  ctx.stroke();
  ctx.fillStyle = "red";
  ctx.fillText("Threshold " + Vt.toFixed(2) + " V", left + plotW - 150, yVt - 5);
 
  // Charging curve
  ctx.strokeStyle = "blue";
  ctx.lineWidth = 2;
  ctx.beginPath();
 
  for (let xPix = 0; xPix <= plotW; xPix++) {
    const tms = xPix * step; // ms
    const Vc  = V_final * (1 - Math.exp(-(tms / 1000) / tau));
    const yPix = top + plotH - (Vc / V_final) * plotH;
 
    const x = left + xPix;
    const y = yPix;
 
    if (xPix === 0) ctx.moveTo(x, y);
    else ctx.lineTo(x, y);
  }
  ctx.stroke();
 
  // Axis labels
  ctx.fillStyle = "black";
  ctx.font = "14px Arial";
 
  // X axis label
  ctx.fillText("Time (ms)", left + plotW / 2 - 35, H - 10);
 
  // Y axis label
  ctx.save();
  ctx.translate(20, top + plotH / 2);
  ctx.rotate(-Math.PI / 2);
  ctx.fillText("Voltage (V)", 0, 0);
  ctx.restore();
}
 
document.getElementById("calcBtn").addEventListener("click", calculate);
</script>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading has-text-align-left" id="h-calculate-time-constant">Calculate Time Constant</h2>



<p class="wp-block-paragraph">The RC Time Calculator uses the following parameters to determine key timing characteristics:</p>



<p class="wp-block-paragraph"><strong>Final capacitor voltage (V_final)</strong> - the final steady-state voltage the capacitor charges to, determined by the resistor divider ratio.<br><strong>Time constant (τ, tau)</strong> -&nbsp; determines the charging speed of the capacitor and depends on the Thevenin equivalent resistance of the divider and the capacitor value.<br><strong>Threshold Voltage (V_threshold)</strong> - the required voltage level at which the target circuit becomes enabled or activated.<br>This is the voltage required, for example, at the Enable pin of a DC-DC converter, or the minimum logic-high level needed by a microcontroller input.<br>The calculator determines how long it takes for the capacitor to charge up to this user-specified threshold.</p>



<p class="wp-block-paragraph">The capacitor in the circuit follows an&nbsp;exponential charging equation:</p>



<p class="wp-block-paragraph">V(t) = <strong>V_final</strong> * (1 - e^(-t / τ))</p>



<p class="wp-block-paragraph">where&nbsp;<strong>V_final</strong>&nbsp;is the final voltage the capacitor will reach,&nbsp;<strong>τ</strong>&nbsp;(tau) is the time constant, and&nbsp;<strong>t</strong>&nbsp;is time.</p>



<p class="wp-block-paragraph">The voltage divider defines the maximum voltage the capacitor will reach:</p>



<p class="wp-block-paragraph"><strong>V_final</strong> = Vin * (R2 / (R1 + R2))</p>



<p class="wp-block-paragraph">The time constant <strong>τ</strong> determines the speed of how the capacitor charges and is calculated as:</p>



<p class="wp-block-paragraph"><strong>τ</strong> = (R1 * R2) / (R1 + R2) * C</p>



<p class="wp-block-paragraph">A higher <strong>τ</strong> value means a slower charge time.</p>



<p class="wp-block-paragraph">To determine the delay before a device turns on, we calculate the time required for the capacitor to reach the specified threshold voltage:</p>



<p class="wp-block-paragraph"><strong>t_enable</strong> = -<strong>τ</strong> * ln(1 - <strong>V_threshold</strong> / <strong>V_final</strong>)</p>



<p class="wp-block-paragraph">This is the startup delay that occurs before the controlled circuit (such as a DC-DC converter or logic input) becomes active.</p>



<p class="wp-block-paragraph">This formula calculates how long it takes for the capacitor voltage to reach the required level.</p>



<h2 id="h-summary" class="wp-block-heading">Summary</h2>



<p class="wp-block-paragraph">The RC Delay Time Calculator models the charging behavior of a capacitor in a voltage divider configuration. It is useful for estimating startup delays, power sequencing timing, enable-pin activation, and analog filtering performance.</p>



<div class="wp-block-group alignwide has-custom-light-blue-background-color has-background is-layout-flow wp-container-core-group-is-layout-dbd34961 wp-block-group-is-layout-flow" style="border-radius:20px;margin-top:var(--wp--preset--spacing--50);margin-bottom:var(--wp--preset--spacing--50);padding-top:var(--wp--preset--spacing--50);padding-right:0;padding-bottom:var(--wp--preset--spacing--50);padding-left:0">
<div class="wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-43efaee5 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--60)">
<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:85%">
<h3 class="wp-block-heading has-text-align-left" id="h-have-an-upcoming-project-dmc-can-help-you-take-the-next-step"><strong>From circuit design to product development, DMC can help bring your idea to life.</strong></h3>



<p class="has-text-align-left wp-block-paragraph" id="h-need-help-turning-ideas-into-outcomes-automation-project-to-the-next-level-contact-us-today-to-learn-more-about-our-solutions-and-how-we-can-help-you-achieve-your-goals">From signal conditioning to custom electronics design, learn how DMC's <a href="https://static.dmcinfo.com/services/embedded-development-and-embedded-programming/" data-type="page" data-id="431">Embedded</a> capabilities can help solve your toughest engineering challenges.</p>
</div>



<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%">
<div class="wp-block-buttons is-horizontal is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-2236275c wp-block-buttons-is-layout-flex">
<div class="wp-block-button is-style-fill"><a class="wp-block-button__link has-base-contrast-color has-text-color has-link-color wp-element-button" href="https://static.dmcinfo.com/contact/">Contact Us</a></div>
</div>
</div>
</div>
</div>
<p>The post <a href="https://static.dmcinfo.com/blog/40375/delay-calculator-for-rc-voltage-divider/">Delay Calculator for RC Voltage Divider</a> appeared first on <a href="https://static.dmcinfo.com/">DMC, Inc.</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
