<?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>Arduino Tutorial Articles | Teach Me Microcontrollers!</title>
	<atom:link href="https://www.teachmemicro.com/category/tutorials/arduino-tutorial/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.teachmemicro.com/category/tutorials/arduino-tutorial/</link>
	<description>Microcontroller Tutorials and Resources</description>
	<lastBuildDate>Mon, 23 Mar 2026 06:32:13 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://www.teachmemicro.com/wp-content/uploads/2019/04/blue-icon-65x65.png</url>
	<title>Arduino Tutorial Articles | Teach Me Microcontrollers!</title>
	<link>https://www.teachmemicro.com/category/tutorials/arduino-tutorial/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Sensor Reading Filtering (Arduino &#038; Embedded Systems)</title>
		<link>https://www.teachmemicro.com/sensor-reading-filtering-arduino-embedded-systems/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=sensor-reading-filtering-arduino-embedded-systems</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 23 Mar 2026 06:32:13 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=10948</guid>

					<description><![CDATA[<p>When I first started working with sensors, I expected clean, stable readings. Instead, what I got were values jumping all over the place. A temperature sensor would fluctuate ±2°C, an ADC reading would jitter constantly, and analog signals were almost unusable without processing. That’s when I realized: raw sensor data is almost always noisy. In &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/sensor-reading-filtering-arduino-embedded-systems/">Sensor Reading Filtering (Arduino &#038; Embedded Systems)</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>When I first started working with sensors, I expected clean, stable readings. Instead, what I got were values jumping all over the place. A temperature sensor would fluctuate ±2°C, an ADC reading would jitter constantly, and analog signals were almost unusable without processing.</p>
<p>That’s when I realized: <strong>raw sensor data is almost always noisy</strong>.</p>
<p>In this article, I’ll walk you through how I handle sensor noise—from the simplest filtering methods to more advanced techniques—and then I’ll give you a reusable filtering library you can drop into your projects.</p>
<p><span id="more-10948"></span></p>
<h3><strong>Why Sensor Readings Are Noisy</strong></h3>
<p>Before filtering, it’s important to understand why noise exists:</p>
<ul>
<li>Electrical noise (power supply, EMI)</li>
<li>ADC quantization errors</li>
<li>Sensor imperfections</li>
<li>Environmental interference</li>
</ul>
<p>For example, even a simple potentiometer read using:</p>
<pre><pre><code class="language-cpp">int value = analogRead(A0);</code></pre></pre>
<p>…will fluctuate slightly even if you don’t touch it.</p>
<h3><strong>1. The Simplest Filter: Delay-Based Stabilization</strong></h3>
<p>The most basic approach I used early on was just adding a delay:</p>
<pre><pre><code class="language-cpp">int read_sensor()
{
   delay(10);
   return analogRead(A0);
}</code></pre></pre>
<p>This kind of works, but it doesn’t actually filter noise—it just slows things down. I don’t recommend relying on this except for quick tests.</p>
<h3><strong>2. Moving Average Filter</strong></h3>
<p>This is the first real filter I use in almost every project.</p>
<p><strong>Idea:</strong></p>
<p>Take multiple samples and average them.</p>
<p><strong>Example:</strong></p>
<pre><pre><code class="language-cpp">#define NUM_SAMPLES 10

int moving_average_read()
{
   long sum = 0;

   for (int i = 0; i &lt; NUM_SAMPLES; i++)
   {
      sum += analogRead(A0);
   }

   return sum / NUM_SAMPLES;
}</code></pre></pre>
<p>What it does:</p>
<ul>
<li>Smooths out random noise</li>
<li>Reduces spikes</li>
</ul>
<p>Tradeoff:</p>
<ul>
<li>Slower response (lag increases with more samples)</li>
</ul>
<h3><strong>3. Running Average </strong></h3>
<p>Instead of recalculating everything, I use a running average.</p>
<pre><pre><code class="language-cpp">#define NUM_SAMPLES 10

int samples[NUM_SAMPLES];
int index = 0;
long total = 0;

int running_average_read()
{
   total -= samples[index];
   samples[index] = analogRead(A0);
   total += samples[index];

   index = (index + 1) % NUM_SAMPLES;

   return total / NUM_SAMPLES;
}</code></pre></pre>
<p>Why I prefer this:</p>
<ul>
<li>Much faster</li>
<li>Works continuously</li>
<li>Great for real-time systems</li>
</ul>
<h3><strong>4. Exponential Moving Average (EMA)</strong></h3>
<p>This is one of my favorite filters because it’s simple and powerful.</p>
<p><strong>Formula:</strong></p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_7d9e3d7c0909618280be67bda8fd0b4c.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="filtered = alpha * newValue + (1 - alpha) * previousFiltered" /></span><script type='math/tex'>filtered = alpha * newValue + (1 - alpha) * previousFiltered</script></p>
<p><strong>Example:</strong></p>
<pre><pre><code class="language-cpp">float alpha = 0.1;

float filtered_value = 0;

float ema_filter(float new_value)
{
   filtered_value = alpha * new_value + (1 - alpha) * filtered_value;
   return filtered_value;
}</code></pre></pre>
<p><strong>Tuning:</strong></p>
<ul>
<li>alpha = 0.1 → very smooth, slow response</li>
<li>alpha = 0.5 → faster response, less smoothing</li>
</ul>
<p><strong>When I use this:</strong></p>
<ul>
<li>Analog sensors (light, temperature, force)</li>
<li>Real-time systems where memory is limited</li>
</ul>
<h3><strong>5. Median Filter </strong></h3>
<p>If your sensor occasionally gives crazy spikes, average filters won’t help much.</p>
<p>That’s where median filtering shines.</p>
<p><strong>Example:</strong></p>
<pre><pre><code class="language-cpp">#define NUM_SAMPLES 5

int median_filter()
{
   int values[NUM_SAMPLES];

   for (int i = 0; i &lt; NUM_SAMPLES; i++)
   {
     values[i] = analogRead(A0);
   }

   // simple sort
   for (int i = 0; i &lt; NUM_SAMPLES - 1; i++)
   {
      for (int j = i + 1; j &lt; NUM_SAMPLES; j++)
      {
         if (values[j] &lt; values[i])
         {
           int temp = values[i];
           values[i] = values[j];
           values[j] = temp;
         }
      }
   }

   return values[NUM_SAMPLES / 2];
}</code></pre></pre>
<p><strong>Why this works:</strong></p>
<ul>
<li>Ignores outliers completely</li>
<li>Perfect for noisy environments</li>
</ul>
<h3><strong>6. Combining Filters </strong></h3>
<p>In real projects, I rarely use just one filter.</p>
<p>A common combo I use:</p>
<p>Median filter → remove spikes<br />
EMA → smooth the result</p>
<p>This gives:</p>
<ul>
<li>Clean signal</li>
<li>Fast response</li>
<li>Good stability</li>
</ul>
<h3><strong>7. Kalman Filter </strong></h3>
<p>When I first heard about Kalman filters, I thought they were only for aerospace or robotics. But once I simplified it, I realized:</p>
<p>A Kalman filter is just a smart way of combining prediction and measurement.</p>
<h4><strong>How It Works (Intuition First)</strong></h4>
<p>Unlike the previous filters, Kalman doesn’t just smooth data.</p>
<p>It does two things every cycle:</p>
<p><strong>1. Predict</strong></p>
<p>It estimates what the next value should be based on previous data.</p>
<p><strong>2. Update</strong></p>
<p>It corrects that prediction using the actual sensor reading.</p>
<h4>Key Idea</h4>
<p>Instead of blindly trusting the sensor:</p>
<p>If the sensor is noisy → trust prediction more<br />
If the sensor is stable → trust measurement more</p>
<blockquote><p>The filter automatically balances both</p></blockquote>
<h4><strong>Simplified Model</strong></h4>
<p>We track two things:</p>
<ul>
<li>Estimated value</li>
<li>Estimated uncertainty</li>
</ul>
<p>Each update adjusts both.</p>
<h4><strong>Simple 1D Kalman Filter Code</strong></h4>
<p>This version is perfect for embedded systems (no matrices).</p>
<pre><pre><code class="language-cpp">typedef struct
{
   float estimate;
   float error_estimate;
   float error_measure;
   float q; // process noise
} kalman_t;

void kalman_init(kalman_t *k, float mea_e, float est_e, float q)
{
   k-&gt;error_measure = mea_e;
   k-&gt;error_estimate = est_e;
   k-&gt;q = q;
   k-&gt;estimate = 0;
}

float kalman_update(kalman_t *k, float measurement)
{
   // Kalman gain
   float kalman_gain = k-&gt;error_estimate /
   (k-&gt;error_estimate + k-&gt;error_measure);

   // Update estimate
   k-&gt;estimate = k-&gt;estimate +
   kalman_gain * (measurement - k-&gt;estimate);

   // Update error estimate
   k-&gt;error_estimate = (1 - kalman_gain) * k-&gt;error_estimate +
   fabs(k-&gt;estimate - measurement) * k-&gt;q;

   return k-&gt;estimate;
}</code></pre></pre>
<h4><strong>What’s Happening Internally</strong></h4>
<p>Let’s break it down simply:</p>
<p><strong>Kalman Gain</strong></p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_71916d2daf03107e56eb3ab196085872.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="K = \frac{errorEstimate}{(errorEstimate + errorMeasure)}" /></span><script type='math/tex'>K = \frac{errorEstimate}{(errorEstimate + errorMeasure)}</script></p>
<ul>
<li>High K → trust measurement more</li>
<li>Low K → trust prediction more</li>
</ul>
<p><strong>Update Step</strong></p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_3aa847105e538b980b06c2ad1c6990f7.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="estimate = estimate + K * (measurement - estimate)" /></span><script type='math/tex'>estimate = estimate + K * (measurement - estimate)</script></p>
<p>This is basically:</p>
<ul>
<li>Take old estimate</li>
<li>Move it toward the new measurement</li>
<li>Amount depends on K</li>
</ul>
<p><strong>Example</strong></p>
<p><em>Sensor readings:</em></p>
<p>10, 11, 50, 12, 11</p>
<p><em>Kalman output:</em></p>
<p>10 → 10.5 → 11 → 11.5 → 11.3</p>
<p>Notice:</p>
<ul>
<li>The spike (50) is heavily reduced</li>
<li>Response is faster than moving average</li>
</ul>
<h4><strong>When I Use Kalman Filter</strong></h4>
<p><strong>I use it when:</strong></p>
<ul>
<li>Sensor is noisy but needs fast response</li>
<li>Combining sensors (e.g., IMU)</li>
<li>Precision matters (robotics, control systems)</li>
</ul>
<p><strong>When NOT to Use It</strong></p>
<p>Avoid Kalman if:</p>
<ul>
<li>Simple EMA already works</li>
<li>You don’t want to tune parameters</li>
<li>System is very resource-constrained</li>
</ul>
<h3><strong>Practical Example: Temperature Sensor</strong></h3>
<p>Let’s say I’m reading a temperature sensor:</p>
<p>Raw: 25.1, 25.3, 24.9, 26.5, 25.0</p>
<p>That 26.5 is likely noise.</p>
<p>After median filter: 25.1, 25.3, 25.0, 25.0, 25.0</p>
<p>After EMA: 25.0 → 25.05 → 25.08 → stable</p>
<p>Now the data is usable.</p>
<h3><strong>A Reusable Filtering Library</strong></h3>
<p>Here’s a simple library I use across projects.</p>
<pre><pre><code class="language-cpp">//filter.h

#ifndef FILTER_H
#define FILTER_H

typedef struct
{
   float alpha;
   float value;
} ema_filter_t;

void ema_init(ema_filter_t *f, float alpha);
float ema_update(ema_filter_t *f, float input);

#endif

//filter.c
#include &quot;filter.h&quot;

void ema_init(ema_filter_t *f, float alpha)
{
   f-&gt;alpha = alpha;
   f-&gt;value = 0;
}

float ema_update(ema_filter_t *f, float input)
{
   f-&gt;value = f-&gt;alpha * input + (1 - f-&gt;alpha) * f-&gt;value;
   return f-&gt;value;
}
Example Usage
#include &quot;filter.h&quot;

ema_filter_t temp_filter;

void setup()
{
   Serial.begin(9600);
   ema_init(&amp;temp_filter, 0.1);
}

void loop()
{
   float raw = analogRead(A0);
   float filtered = ema_update(&amp;temp_filter, raw);

   Serial.print(&quot;Raw: &quot;);
   Serial.print(raw);
   Serial.print(&quot; Filtered: &quot;);
   Serial.println(filtered);

   delay(100);
}</code></pre></pre>
<h3><strong>Choosing the Right Filter</strong></h3>
<p>Here’s how I usually decide:</p>

<table id="tablepress-2" class="tablepress tablepress-id-2">
<thead>
<tr class="row-1">
	<th class="column-1">Situation</th><th class="column-2">Filter</th>
</tr>
</thead>
<tbody class="row-striping row-hover">
<tr class="row-2">
	<td class="column-1">Random noise</td><td class="column-2">Moving Average/EMA</td>
</tr>
<tr class="row-3">
	<td class="column-1">Fast system</td><td class="column-2">EMA</td>
</tr>
<tr class="row-4">
	<td class="column-1">Spikes/outliers</td><td class="column-2">Median</td>
</tr>
<tr class="row-5">
	<td class="column-1">High precision</td><td class="column-2">Combine filters</td>
</tr>
</tbody>
</table>
<!-- #tablepress-2 from cache -->
<p>&nbsp;</p>
<h3><strong>Final Thoughts</strong></h3>
<p>If there’s one thing I’ve learned, it’s this:</p>
<blockquote><p>Filtering is not optional—it’s part of reading a sensor.</p></blockquote>
<p>The difference between a “working” project and a “reliable” one often comes down to how well you handle noise.</p>
<p>The post <a href="https://www.teachmemicro.com/sensor-reading-filtering-arduino-embedded-systems/">Sensor Reading Filtering (Arduino &#038; Embedded Systems)</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Using the MH-ET LIVE Scanner 3.0 (QR/Barcode) with Arduino</title>
		<link>https://www.teachmemicro.com/using-the-mh-et-live-scanner-3-0-qr-barcode-with-arduino/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=using-the-mh-et-live-scanner-3-0-qr-barcode-with-arduino</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 01 Dec 2025 02:58:58 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=10100</guid>

					<description><![CDATA[<p>This guide shows how to interface the MH-ET LIVE Scanner V3.0 with Arduino using the UART serial interface. This scanner can read 1D barcodes and 2D codes including QR, and outputs the decoded text through UART or USB. 1. Overview of the Module Your MH-ET Scanner board includes: 2D scanning engine (CMOS sensor + decoder) &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/using-the-mh-et-live-scanner-3-0-qr-barcode-with-arduino/">Using the MH-ET LIVE Scanner 3.0 (QR/Barcode) with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This guide shows how to interface the MH-ET LIVE Scanner V3.0 with Arduino using the UART serial interface. This scanner can read <strong>1D barcodes</strong> and <strong>2D codes including QR</strong>, and outputs the decoded text through UART or USB.</p>
<p><span id="more-10100"></span></p>
<hr />
<h3><strong>1. Overview of the Module</strong></h3>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-scanner-iso.avif"><img data-dominant-color="c9c8c8" data-has-transparency="false" style="--dominant-color: #c9c8c8;" decoding="async" class="aligncenter size-full wp-image-10101 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-scanner-iso.avif" alt="MH ET Live QR Scanner" width="600" height="600" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-scanner-iso.avif 600w, https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-scanner-iso-300x300.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-scanner-iso-150x150.avif 150w" sizes="(max-width: 600px) 100vw, 600px" /></a></p>
<p>Your MH-ET Scanner board includes:</p>
<ul>
<li><strong>2D scanning engine</strong> (CMOS sensor + decoder)</li>
<li><strong>Two Micro-USB ports</strong>
<ul>
<li><strong>UART USB</strong> → Virtual COM port</li>
<li><strong>HID USB</strong> → Emulates a keyboard</li>
</ul>
</li>
<li><strong>6-pin interface block</strong> containing:
<ul>
<li><strong>UART-TX / UART-RX</strong></li>
<li><strong>S-TX / S-RX</strong> (raw TTL UART, ideal for Arduino)</li>
<li><strong>HID-TX / HID-RX</strong></li>
</ul>
</li>
<li><strong>Two jumper headers</strong>
<ul>
<li>Selects which interface connects to the scanner engine</li>
</ul>
</li>
<li><strong>RST pin</strong> for hardware reset</li>
<li><strong>VCC / GND</strong> for power (5V required)</li>
</ul>
<hr />
<h3><strong>2. Understanding the 6-Pin Header &amp; Jumper Settings</strong></h3>
<p>The key to using this module is understanding how data flows.</p>
<h4>6-Pin Header (left → right)</h4>
<div class="_tableContainer_1rjym_1">
<div class="group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse" tabindex="-1">
<table class="w-fit min-w-(--thread-content-width)">
<thead>
<tr>
<th data-col-size="sm">Pin block</th>
<th data-col-size="md">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td data-col-size="sm"><strong>UART-TX / UART-RX</strong></td>
<td data-col-size="md">Connected to the USB-UART chip (via UART microUSB)</td>
</tr>
<tr>
<td data-col-size="sm"><strong>S-TX / S-RX</strong></td>
<td data-col-size="md"><strong>Raw 5V UART pins for microcontrollers</strong></td>
</tr>
<tr>
<td data-col-size="sm"><strong>HID-TX / HID-RX</strong></td>
<td data-col-size="md">Connected to HID-USB chip (keyboard mode)</td>
</tr>
</tbody>
</table>
</div>
</div>
<h4>Jumper Selection</h4>
<p>There are two jumpers:</p>
<ul>
<li><strong>UART ←→ S</strong>: Connect S-TX/RX to USB-UART chip</li>
<li><strong>HID ←→ S</strong>: Connect S-TX/RX to USB-HID chip</li>
</ul>
<p>For Arduino, we <strong>do not use the jumpers at all</strong> — we directly wire to <strong>S-TX</strong> and <strong>S-RX</strong>, which always connect to the scanner engine.</p>
<hr />
<h3><strong>3. Power Requirements</strong></h3>
<p>The scanner <strong>must be powered at 5V</strong>, not 3.3V.<br />
At 3.3V, the LED driver and CMOS sensor do not get enough current → <strong>QR codes fail to scan.</strong></p>
<p>Recommended:</p>
<ul>
<li><strong>5V / 500mA</strong> supply</li>
<li>Add <strong>100 µF capacitor</strong> across VCC–GND if using long wires</li>
</ul>
<hr />
<h3><strong>4. Wiring the Module to Arduino</strong></h3>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-arduino-wiring.avif"><img data-dominant-color="b1bebe" data-has-transparency="false" style="--dominant-color: #b1bebe;" loading="lazy" decoding="async" class="aligncenter size-full wp-image-10104 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-arduino-wiring.avif" alt="MH-ET Live QR code scanner arduino wiring diagram" width="1024" height="585" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-arduino-wiring.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-arduino-wiring-300x171.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/12/mh-et-live-qr-arduino-wiring-768x439.avif 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></a></p>
<h4>Arduino UNO / Nano WIRING</h4>
<div class="_tableContainer_1rjym_1">
<div class="group _tableWrapper_1rjym_13 flex w-fit flex-col-reverse" tabindex="-1">
<table class="w-fit min-w-(--thread-content-width)">
<thead>
<tr>
<th data-col-size="sm">Scanner Pin</th>
<th data-col-size="sm">Arduino Pin</th>
</tr>
</thead>
<tbody>
<tr>
<td data-col-size="sm"><strong>S-TX</strong></td>
<td data-col-size="sm"><strong>D2</strong> (Arduino RX using SoftwareSerial)</td>
</tr>
<tr>
<td data-col-size="sm"><strong>S-RX</strong></td>
<td data-col-size="sm"><strong>D3</strong> (Arduino TX using SoftwareSerial)</td>
</tr>
<tr>
<td data-col-size="sm"><strong>RST</strong></td>
<td data-col-size="sm"><strong>D4 </strong>(not pictured, optional)</td>
</tr>
<tr>
<td data-col-size="sm"><strong>VCC</strong></td>
<td data-col-size="sm"><strong>5V</strong></td>
</tr>
<tr>
<td data-col-size="sm"><strong>GND</strong></td>
<td data-col-size="sm"><strong>GND</strong></td>
</tr>
</tbody>
</table>
</div>
</div>
<p><strong>S-TX → Arduino RX</strong><br />
<strong>S-RX → Arduino TX</strong><br />
(TX always goes to the other device’s RX)</p>
<hr />
<h3><strong>5. Arduino Code (Tested &amp; Working)</strong></h3>
<p>This code:</p>
<ul>
<li>Initializes serial communication</li>
<li>Listens for decoded data</li>
<li>Resets the scanner if needed</li>
<li>Prints QR/barcode results to Serial Monitor</li>
</ul>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-cpp">#include &lt;SoftwareSerial.h&gt;

#define SCANNER_RX 2   // S-TX from scanner → Arduino D2 (RX)
#define SCANNER_TX 3   // S-RX from scanner → Arduino D3 (TX)
#define RST_PIN    4   // Reset pin for scanner engine

SoftwareSerial scanner(SCANNER_RX, SCANNER_TX);

void scannerReset() {
  digitalWrite(RST_PIN, LOW);
  delay(20);
  digitalWrite(RST_PIN, HIGH);
  delay(500);  // scanner reboot time
}

void setup() {
  pinMode(RST_PIN, OUTPUT);
  digitalWrite(RST_PIN, HIGH);

  Serial.begin(9600);
  scanner.begin(9600);    // Some units use 115200

  Serial.println("Scanner ready...");
  scannerReset();
}

void loop() {
  if (scanner.available()) {
    String data = scanner.readStringUntil('\n');
    data.trim();
    if (data.length() &gt; 0) {
      Serial.print("Scanned: ");
      Serial.println(data);
    }
  }
}
</code></pre>
</div>
</div>
<hr />
<h3><strong>6. Confirming Baud Rate</strong></h3>
<p>Most units default to <strong>9600</strong>, but some ship at <strong>115200</strong>.</p>
<p>If you see:</p>
<ul>
<li>Random characters</li>
<li>Half-printed QR values</li>
<li>Nothing at all</li>
</ul>
<p>Try:</p>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-cpp">scanner.begin(115200);
</code></pre>
</div>
</div>
<hr />
<h3><strong>7. Reset Pin (RST) Details</strong></h3>
<p>The scanner’s <strong>RST pin is active LOW</strong>:</p>
<ul>
<li>Pull LOW 10–20 ms → module resets</li>
<li>Releases HIGH → boots in ~500 ms</li>
</ul>
<p>This is helpful if:</p>
<ul>
<li>Scanner stops responding</li>
<li>Power dips</li>
<li>Switching between HID/UART modes</li>
<li>After scanning configuration QR codes</li>
</ul>
<hr />
<h3><strong>8. Testing QR &amp; Barcode Scanning</strong></h3>
<p>For reliable scanning:</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Use 5V power</h4>
<p>3.3V causes QR detection to fail.</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Ideal scan distance</h4>
<p><strong>10–20 cm</strong> away<br />
(QR is most sensitive to focus distance.)</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Best QR size</h4>
<p><strong>25–30 mm</strong> square</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Avoid shiny screens and reflections</h4>
<p>If scanning fails:</p>
<ul>
<li>Increase ambient lighting</li>
<li>Move slightly farther/closer</li>
<li>Try a simpler QR (Hello World)</li>
</ul>
<hr />
<h3><strong>9. Using USB Modes (Optional)</strong></h3>
<h4><strong>A. USB-UART Mode</strong></h4>
<p>Jumper <strong>UART <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2194.png" alt="↔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> S</strong><br />
Then connect <strong>UART microUSB → PC</strong><br />
Open PuTTY / TeraTerm, baud = 9600</p>
<h4><strong>B. USB-HID Mode</strong></h4>
<p>Jumper <strong>HID <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2194.png" alt="↔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> S</strong><br />
Then connect <strong>HID microUSB</strong><br />
Scanner types text like a keyboard.</p>
<hr />
<h3><strong>10. Troubleshooting</strong></h3>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Scanner reads no QR codes</h4>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fix: Use <strong>5V</strong>, not 3.3V<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fix: Correct distance (15–20 cm)</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Only 1D barcodes read</h4>
<p>Scanner may be in <strong>1D-only mode</strong><br />
→ Scan configuration QR to enable 2D.</p>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Arduino receives gibberish</h4>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Baud rate mismatch<br />
<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Long wires → noise</h4>
<h4><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Scanner freezes</h4>
<p><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2714.png" alt="✔" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Call <pre><code class="language-cpp">scannerReset();</code></pre></p>
<hr />
<h3><strong>11. Bonus: Auto-Recover Watchdog</strong></h3>
<p>If scanner becomes idle/unresponsive:</p>
<div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary">
<div class="sticky top-9">
<div class="absolute end-0 bottom-0 flex h-9 items-center pe-2">
<div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"></div>
</div>
</div>
<div class="overflow-y-auto p-4" dir="ltr">
<pre><code class="whitespace-pre! language-cpp">unsigned long lastScan = millis();

void loop() {
  if (scanner.available()) {
    char c = scanner.read();
    Serial.write(c);
    lastScan = millis();
  }

  if (millis() - lastScan &gt; 7000) {
    Serial.println("Resetting scanner...");
    scannerReset();
    lastScan = millis();
  }
}
</code></pre>
</div>
</div>
<hr />
<h3>12. Testing Other Modes and Configurations</h3>
<p>The MH-ET Live QR code scanner supports a lot of configuration options. You can switch between the options by directly scanning pre-defined QR codes. The configuration QR codes can be viewed in <a href="https://e-gizmo.net/oc/kits%20documents/scannerv3/Scanner%20v3.0%20QR%20code%20module%20specification.pdf">this document</a>.</p>
<h3><strong>Finished!</strong></h3>
<p>You now have a complete working setup for:</p>
<ul>
<li>Reading QR codes</li>
<li>Reading 1D barcodes</li>
<li>Hardware reset via RST</li>
<li>UART communication via S-TX/S-RX</li>
<li>Arduino-compatible powering</li>
<li>Full troubleshooting and configuration process</li>
</ul>
<p>The post <a href="https://www.teachmemicro.com/using-the-mh-et-live-scanner-3-0-qr-barcode-with-arduino/">Using the MH-ET LIVE Scanner 3.0 (QR/Barcode) with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>CISC vs RISC for an Arduino User</title>
		<link>https://www.teachmemicro.com/cisc-vs-risc-for-an-arduino-user/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cisc-vs-risc-for-an-arduino-user</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Sat, 22 Nov 2025 01:12:07 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=10012</guid>

					<description><![CDATA[<p>Introduction Whenever I peel back the layers of how my Arduino boards actually work, I always end up revisiting one classic topic: CISC vs RISC. When I first heard those terms, I honestly thought they were meant for chip architects wearing lab coats inside semiconductor fabs. But the more I built projects — robots, IoT &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/cisc-vs-risc-for-an-arduino-user/">CISC vs RISC for an Arduino User</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h3><strong>Introduction</strong></h3>
<p>Whenever I peel back the layers of how my Arduino boards actually work, I always end up revisiting one classic topic: <strong>CISC vs RISC</strong>.</p>
<p>When I first heard those terms, I honestly thought they were meant for chip architects wearing lab coats inside semiconductor fabs. But the more I built projects — robots, IoT sensors, timing-critical systems — the more I realized that understanding these architectures <em>directly affects how my Arduino projects behave in the real world</em>.</p>
<p>This guide is my attempt to explain everything the way I wish someone explained it to me years ago:<br />
<strong>simple, real, and from the perspective of someone actually using Arduino boards daily.</strong></p>
<p>No jargon walls. No engineering jargon that makes your eyes glaze over.<br />
Just plain talk about what’s really going on under the hood.</p>
<hr />
<h3><strong>Understanding CPU Architectures </strong></h3>
<h4><strong>What Is a CPU Instruction Set?</strong></h4>
<p>Every time I upload a sketch to my Arduino, that human-friendly C/C++ code eventually gets translated into tiny machine instructions — microscopic tasks that the chip understands.</p>
<p>These instructions are things like:</p>
<ul>
<li>add two numbers</li>
<li>compare values</li>
<li>read a pin</li>
<li>jump to another part of the program</li>
</ul>
<p>The entire “dictionary” of instructions that a CPU understands is its <strong>instruction set</strong>.</p>
<p>Different CPU families simply have <em>different dictionaries</em>.<br />
Some have a small collection of straight-to-the-point words.<br />
Others have a huge library of fancy phrases.</p>
<p>That’s where RISC and CISC philosophies come from.</p>
<hr />
<h4><strong>How Microcontrollers Actually Use Instructions</strong></h4>
<p>Inside the microcontroller, there’s a never-ending loop:</p>
<ol>
<li>fetch an instruction</li>
<li>decode it</li>
<li>execute it</li>
<li>repeat</li>
</ol>
<p>The style of the instruction set (CISC or RISC) affects:</p>
<ul>
<li>how fast each instruction runs</li>
<li>how predictable the timing is</li>
<li>how much power the chip consumes</li>
<li>what kinds of operations the chip can perform directly</li>
</ul>
<p>This is why architecture matters even in simple Arduino sketches — it influences everything from <pre><code class="language-cpp">digitalWrite()</code></pre> speed to how long your battery lasts.</p>
<hr />
<h3><strong>What Is CISC?</strong></h3>
<p>I like thinking of <strong>CISC (Complex Instruction Set Computer)</strong> as the “giant toolbox” approach.</p>
<p>It includes lots of instructions, some of which can perform surprisingly complex operations in just a single command. A single CISC instruction might:</p>
<ul>
<li>load data</li>
<li>modify it</li>
<li>store it again</li>
</ul>
<p>…all in one shot.</p>
<p>This is convenient if the programmer is working at the assembly level since one line replaces many.</p>
<h3><strong>Key Features of CISC </strong></h3>
<ul>
<li><strong>Large instruction set</strong> → lots of “tool shapes” for many scenarios</li>
<li><strong>Complex instructions</strong> → one instruction may do several steps</li>
<li><strong>Microcode is common</strong> → the CPU contains a small internal translator that breaks down those big instructions</li>
<li><strong>Often higher energy use</strong> → complexity has a cost</li>
</ul>
<h3><strong>Why CISC Is Useful</strong></h3>
<p>I learned that CISC instructions can feel like shortcuts. You can write fewer lines of low-level code to accomplish a task. That’s why CISC dominated desktop CPUs — they needed powerful, flexible instructions.</p>
<h3><strong>Where CISC Falls Short</strong></h3>
<p>The same complexity that makes CISC powerful also slows it down. Complex instructions need more circuits to decode, and they may take multiple cycles to execute.</p>
<p>Battery-powered devices don’t like that.</p>
<hr />
<h3><strong>What Is RISC?</strong></h3>
<p><strong>RISC (Reduced Instruction Set Computer)</strong> is the complete opposite philosophy — a minimalist approach.</p>
<p>I imagine RISC as a clean, well-organized toolbox containing only the most essential tools. Nothing unnecessary. Nothing fancy. But every tool is extremely efficient.</p>
<h3><strong>Key Features of RISC </strong></h3>
<ul>
<li><strong>Small instruction set</strong> → fewer but faster instructions</li>
<li><strong>Each instruction does one thing</strong> → no hidden complexity</li>
<li><strong>Each instruction completes in one cycle</strong> (in many cases)</li>
<li><strong>Timing becomes predictable</strong> → perfect for robotics and real-time tasks</li>
<li><strong>High efficiency</strong> → makes RISC great for battery-powered devices</li>
</ul>
<h3><strong>Where RISC Shines</strong></h3>
<p>RISC chips often outperform CISC chips at lower power because they do simple things quickly and consistently. Even when a task needs more instructions, the sheer speed of each instruction often makes up for it.</p>
<h3><strong>The Tradeoff</strong></h3>
<p>Complex tasks may require more lines of low-level code. But since Arduino hides assembly from most users, we rarely see this downside.</p>
<hr />
<h3><strong>CISC vs RISC: How I Personally Compare Them</strong></h3>
<p>When I look at the two architectures, here’s how they feel:</p>
<ul>
<li><strong>CISC = Swiss Army knife</strong><br />
Great when you need special tools but slower to open.</li>
<li><strong>RISC = clean toolbox with fast, efficient tools</strong><br />
Fewer choices, but every tool is sharp and quick.</li>
</ul>
<p>Both work. They just approach the job differently.</p>
<hr />
<h3><strong>How CISC vs RISC Actually Affects My Arduino Projects</strong></h3>
<h4><strong>AVR (Arduino Uno, Nano, Mega) — CISC-ish Behavior</strong></h4>
<p>AVR isn’t fully CISC, but it clearly leans in that direction.<br />
Some instructions are multi-step and fairly complex.</p>
<p>Things I’ve noticed in real use:</p>
<ul>
<li>predictable behavior</li>
<li>great for learning</li>
<li>starts to feel slow when projects get more demanding</li>
<li>consumes more power compared to modern microcontrollers</li>
</ul>
<p>This is why an Arduino Uno struggles with heavy math or fast interrupts compared to modern boards.</p>
<hr />
<h4><strong>ARM-Based Arduino Boards (Due, Nano 33 IoT, Portenta) — Pure RISC</strong></h4>
<p>Whenever I use an ARM Cortex-based board, everything feels snappier. That’s the RISC advantage kicking in.</p>
<p>The biggest benefits I personally see:</p>
<ul>
<li><strong>faster loop speeds</strong></li>
<li><strong>less power usage</strong></li>
<li><strong>better handling of sensors and real-time tasks</strong></li>
<li><strong>way faster math operations</strong></li>
<li><strong>much lower latency in GPIO operations</strong></li>
</ul>
<p>For example, the first time I tested <pre><code class="language-cpp">digitalWrite()</code></pre> on an ARM board, I genuinely thought something was wrong — it was that fast.</p>
<hr />
<h3><strong>The Real Examples That Made Things “Click" for Me</strong></h3>
<h3><strong>1. digitalWrite() Speed</strong></h3>
<p>On AVR, <em>digitalWrite()</em> can take several microseconds.<br />
On ARM, it’s <em>orders of magnitude</em> faster.</p>
<p>The first time I saw the oscilloscope trace, I understood immediately: “Okay, RISC is different.”</p>
<h3><strong>2. Tight Loops and Floating Point Math</strong></h3>
<p>AVR struggles heavily here.<br />
ARM breezes through it.</p>
<p>I had sketches that lagged on the Uno but felt instant on the Due.</p>
<hr />
<h3><strong>Which Architecture Do I Personally Prefer?</strong></h3>
<p><strong>For beginners</strong><br />
→ AVR boards still feel warm and friendly. Perfect for LED, sensor, and classroom projects.</p>
<p><strong>For performance</strong><br />
→ RISC every time. Robotics, IoT, signal processing, and battery-powered projects benefit enormously from the ARM architecture.</p>
<hr />
<h3><strong>Advanced Insights I Use When Optimizing Arduino Code</strong></h3>
<ul>
<li><strong>RISC timing is predictable</strong>: each instruction generally takes one cycle, which helps when I’m doing real-time logic.</li>
<li><strong>CISC gives me “shortcut instructions”</strong>: helpful when working with assembly or optimizing low-level AVR routines.</li>
<li><strong>RISC pipelines well</strong>: instructions flow through the CPU like a well-oiled machine.</li>
</ul>
<p>Both architectures have optimization potential — just in different ways.</p>
<hr />
<h3><strong>Industry Trends I’m Seeing Everywhere</strong></h3>
<p>Almost every new microcontroller today uses a RISC architecture:</p>
<ul>
<li>ARM Cortex series</li>
<li>ESP32</li>
<li>RISC-V development boards</li>
<li>even some AI/ML-focused microcontrollers</li>
</ul>
<p>Even desktop CPUs like Intel’s x86 chips have quietly adopted RISC-like operations internally — they translate CISC instructions into RISC micro-ops behind the scenes.</p>
<p>RISC has simply become the most energy-efficient and practical design for modern embedded systems.</p>
<hr />
<h3><strong>Frequently Asked Questions</strong></h3>
<p><strong>1. Which Arduino boards actually use CISC?</strong><br />
The Uno, Mega, and Nano use AVR chips, which lean toward CISC.</p>
<p><strong>2. Are RISC-based Arduino boards faster?</strong><br />
From my own experience — absolutely yes.</p>
<p><strong>3. Do beginners need to worry about this?</strong><br />
Not at all. But knowing the difference helps as you build bigger projects.</p>
<p><strong>4. Why is ARM considered RISC?</strong><br />
ARM uses a simple, uniform instruction set designed for predictable, fast execution.</p>
<p><strong>5. Are RISC boards better for battery-powered projects?</strong><br />
Yes — their power efficiency is a major advantage.</p>
<p><strong>6. Will this affect Arduino libraries?</strong><br />
No — the Arduino ecosystem is designed to handle multiple architectures seamlessly.</p>
<hr />
<h3><strong>Conclusion</strong></h3>
<p>Understanding CISC vs RISC genuinely changed the way I choose Arduino boards for my projects.</p>
<p>Both architectures can run the same Arduino sketches just fine — but they work very differently.<br />
CISC gives you powerful, complex instructions, while RISC keeps things simple, fast, and efficient.</p>
<p>When I’m blinking LEDs, both work.<br />
But when I’m building a robot, managing real-time sensors, or optimizing power consumption, RISC-based boards give me noticeable advantages.</p>
<p>Knowing how your microcontroller “thinks” helps you pick the right board and build better projects — and that’s what makes this topic worth understanding.</p>
<p>The post <a href="https://www.teachmemicro.com/cisc-vs-risc-for-an-arduino-user/">CISC vs RISC for an Arduino User</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Use the PT100 RTD with Arduino Cloud</title>
		<link>https://www.teachmemicro.com/pt100-rtd-arduino-cloud/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=pt100-rtd-arduino-cloud</link>
					<comments>https://www.teachmemicro.com/pt100-rtd-arduino-cloud/#respond</comments>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 13 Nov 2024 01:00:41 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=1914</guid>

					<description><![CDATA[<p>Using a PT100 RTD (Resistance Temperature Detector) with an Arduino and connecting it to the Arduino IoT Cloud via Wi-Fi allows you to remotely monitor temperatures with high accuracy and reliability. In this tutorial, we’ll walk you through the process of setting up your PT100 sensor with an Arduino that has Wi-Fi capabilities, and then &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/pt100-rtd-arduino-cloud/">How to Use the PT100 RTD with Arduino Cloud</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Using a PT100 RTD (Resistance Temperature Detector) with an Arduino and connecting it to the Arduino IoT Cloud via Wi-Fi allows you to remotely monitor temperatures with high accuracy and reliability. In this tutorial, we’ll walk you through the process of setting up your PT100 sensor with an Arduino that has Wi-Fi capabilities, and then integrate the data into Arduino Cloud for remote monitoring and logging.</p>
<p><span id="more-1914"></span></p>
<h3>What You’ll Need</h3>
<ol>
<li><strong>PT100 RTD Temperature Sensor</strong></li>
<li><strong>RTD Amplifier/Module</strong> – For example, an <em>Adafruit MAX31865 Amplifier</em>, which is specifically designed for RTDs.</li>
<li><strong>Arduino with Wi-Fi capability</strong> – Arduino MKR WiFi 1010 , ESP32, or similar.</li>
<li><strong>Jumper wires</strong></li>
<li><strong>Arduino IoT Cloud Account</strong></li>
</ol>
<h3>Understanding the PT100 Sensor and Amplifier</h3>
<p><img decoding="async" src="https://www.makerlab-electronics.com/cdn/shop/products/Adafruit-PT100-RTD-Temperature-Sensor-Amplifier-MAX31865_50406be6-1e1a-4aea-8049-c50b169eaef7.jpg?v=1679473105&amp;width=1946" alt="Adafruit PT100 RTD Temperature Sensor Amplifier - MAX31865" class="aligncenter" /></p>
<p>The PT100 RTD sensor changes resistance in response to temperature. The PT100’s resistance is 100 ohms at 0°C and changes linearly with temperature. To interface it with the Arduino, you need an amplifier like the MAX31865, which converts the resistance changes into digital signals readable by the Arduino.</p>
<h3>Wiring the PT100 RTD and Amplifier</h3>
<p>Connect the PT100 RTD to the amplifier. Most RTD amplifiers like the MAX31865 come with labeled inputs for 2-wire, 3-wire, or 4-wire RTD configurations. Here’s how to connect a 3-wire PT100 RTD to a MAX31865 module and then connect the module to the Arduino</p>
<p><strong>PT100 Sensor to MAX31865</strong>:</p>
<ul>
<li>Wire one side of the RTD to the RTD+ pin.</li>
<li>The other two wires go to the RTD- and RTD Middle connections (follow the specific module’s labeling).</li>
</ul>
<p><strong>MAX31865 Amplifier to Arduino</strong>:</p>
<ul>
<li>VCC of the MAX31865 to 3.3V on the Arduino.</li>
<li>GND of the MAX31865 to GND on the Arduino.</li>
<li>SDO (MISO) of the MAX31865 to MISO on the Arduino.</li>
<li>SDI&gt; (MOSI) of the MAX31865 to MOSI on the Arduino.</li>
<li>SCK of the MAX31865 to SCK on the Arduino.</li>
<li>CS&gt; of the MAX31865 to any available digital pin on the Arduino (e.g., D5).</li>
</ul>
<h3>Install Required Libraries</h3>
<p>To make your Arduino code simpler, install the required libraries:</p>
<p><strong>Adafruit MAX31865 Library</strong>:</p>
<ul>
<li>Open the Arduino IDE.</li>
<li>Go to <em>Sketch &gt; Include Library &gt; Manage Libraries</em>.</li>
<li>Search for <em>Adafruit MAX31865</em> and install it.</li>
</ul>
<p><strong>Arduino IoT Cloud Library</strong>:</p>
<ul>
<li>Go to <em>Sketch&gt; Include Library&gt; Manage Libraries</em></li>
<li>Search for <em>ArduinoIoTCloud</em> and install it.</li>
</ul>
<h3>Step 4: Create an Arduino IoT Cloud Account and Setup a New Thing</h3>
<ol>
<li>Go to <a rel="noopener" target="_new"><span>Arduino</span><span> IoT</span><span> Cloud</span></a> and sign in or create an account.</li>
<li>Create a new <strong>Thing</strong> in the Arduino IoT Cloud, which will be the object holding your temperature data.</li>
<li>Define a variable in the Thing (e.g., <em>temperature</em> of type <em>Float)</em> that will store and display the PT100 sensor’s temperature readings.</li>
<li>Select your device type and configure it to connect to Wi-Fi.</li>
</ol>
<h3>Step 5: Write the Arduino Code</h3>
<p>Here’s an example code snippet to read from the PT100 sensor and upload the data to Arduino Cloud.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;Adafruit_MAX31865.h&gt;&lt;adafruit_max31865.h&gt;
#include &lt;ArduinoIoTCloud.h&gt;&lt;arduinoiotcloud.h&gt;
#include &lt;WiFiNINA.h&gt;&lt;wifinina.h&gt;

// Wi-Fi credentials
const char* ssid = &quot;Your_SSID&quot;;
const char* password = &quot;Your_PASSWORD&quot;;

// MAX31865 configuration
#define MAX31865_CS_PIN 5  // Chip Select pin
Adafruit_MAX31865 max31865 = Adafruit_MAX31865(MAX31865_CS_PIN);

// Arduino Cloud variable
float temperature;

// Function to read temperature from the PT100 sensor
float readTemperature() {
  // Configure the RTD sensor type
  max31865.begin(MAX31865_3WIRE);  // Choose the right wiring configuration (2, 3, or 4 wire)
  float temp = max31865.temperature(100, 430);  // 100 ohms for PT100, 430 is the reference resistor
  return temp;
}

// IoT Cloud setup
void initProperties() {
  ArduinoCloud.addProperty(temperature, READ, ON_CHANGE, NULL);
}

void setup() {
  Serial.begin(9600);

  // Initialize MAX31865
  if (!max31865.begin(MAX31865_3WIRE)) {
    Serial.println(&quot;Failed to initialize MAX31865!&quot;);
    while (1);
  }
  
  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(&quot;.&quot;);
  }
  Serial.println(&quot;Connected to WiFi!&quot;);

  // Arduino IoT Cloud setup
  initProperties();
  ArduinoCloud.begin(WiFi.status);
}

void loop() {
  // Update Arduino IoT Cloud
  ArduinoCloud.update();

  // Read temperature and print it to Serial
  temperature = readTemperature();
  Serial.print(&quot;Temperature: &quot;);
  Serial.println(temperature);

  // Delay for stability
  delay(2000);
}
&lt;/wifinina.h&gt;&lt;/arduinoiotcloud.h&gt;&lt;/adafruit_max31865.h&gt;</code></pre></pre>
</div>
</div>
</div>
<h3>Code Explanation</h3>
<ol>
<li><strong>Wi-Fi Configuration</strong>: The code connects to your Wi-Fi using <em>WiFiNINA.h</em>.</li>
<li><strong>RTD Setup</strong>: The <em>Adafruit_MAX31865</em> library configures the sensor with <em>max31865.begin(MAX31865_3WIRE)</em>.</li>
<li><strong>Temperature Readings</strong>: <em>temperature = readTemperature()</em> fetches the temperature and assigns it to the temperature variable created in Arduino Cloud.</li>
<li><strong>Sending Data to the Cloud</strong>: <em>ArduinoCloud.update()</em> syncs the temperature data to your Arduino IoT Cloud account.</li>
</ol>
<h3>Monitoring Data on Arduino IoT Cloud</h3>
<ol>
<li>Go back to Arduino IoT Cloud and open the <strong>Dashboard</strong> for your Thing.</li>
<li>Add a widget (such as a <strong>Gauge</strong> or <strong>Chart</strong>) to visualize the <em>temperature</em> variable in real-time.</li>
</ol>
<h3>Deploy and Test</h3>
<ol>
<li>Upload the code to your Arduino board.</li>
<li>Open the serial monitor to verify if temperature readings are displayed correctly.</li>
<li>Check the Arduino IoT Cloud dashboard to ensure the temperature data is streaming and updating in real-time.</li>
</ol>
<h3>Conclusion</h3>
<p>This tutorial demonstrated how to connect a PT100 RTD to an Arduino with Wi-Fi capability and integrate it into Arduino IoT Cloud. This setup is suitable for remote monitoring, data logging, and implementing smart temperature monitoring systems. You can further customize the setup by adding more features, such as email alerts or integration with other IoT services.</p>
<p>For additional resources on sensor integrations and IoT projects, visit <a rel="noopener" target="_new" href="https://www.miband.org/"><span>MiBand</span><span>.org</span></a>, a valuable platform for IoT enthusiasts looking to expand their knowledge and projects.</p>
<p>The post <a href="https://www.teachmemicro.com/pt100-rtd-arduino-cloud/">How to Use the PT100 RTD with Arduino Cloud</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.teachmemicro.com/pt100-rtd-arduino-cloud/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Binary Search and Its Application on Arduino</title>
		<link>https://www.teachmemicro.com/binary-search-and-its-application-on-arduino/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=binary-search-and-its-application-on-arduino</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 06 Nov 2024 22:53:00 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7479</guid>

					<description><![CDATA[<p>Binary search is an efficient search algorithm that is particularly useful for finding elements in a sorted array. In comparison to linear search, which goes through each element one by one, binary search dramatically reduces the number of comparisons by dividing the search interval in half repeatedly. This is especially helpful for applications on resource-constrained &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/binary-search-and-its-application-on-arduino/">Binary Search and Its Application on Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Binary search is an efficient search algorithm that is particularly useful for finding elements in a sorted array. In comparison to linear search, which goes through each element one by one, binary search dramatically reduces the number of comparisons by dividing the search interval in half repeatedly. This is especially helpful for applications on resource-constrained microcontrollers like the Arduino.</p>
<p><span id="more-7479"></span></p>
<p>In this tutorial, we’ll cover:</p>
<div class="checklist tie-list-shortcode">
<ul>
<li><strong>What is Binary Search?</strong></li>
<li><strong>Implementing Binary Search on Arduino</strong></li>
<li><strong>Using Binary Search to Map Values on Arduino</strong></li>
</ul>
</div>
<hr />
<h3>What is Binary Search?</h3>
<p>&nbsp;</p>
<p>Binary search works on a sorted array by repeatedly dividing the search interval in half. If the target value is less than the value in the middle of the interval, the search continues on the left half; otherwise, it continues on the right half. This division continues until the target is found or the interval is empty.</p>
<p><strong>Binary Search Characteristics:</strong></p>
<ul>
<li><strong>Time Complexity: </strong><em><span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord mathnormal">O</span><span class="mopen">(</span><span class="mop">log</span><span class="mspace"></span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span></em>, which is much faster than a linear search's<span style="font-family: math;"> </span><em><span class="katex"><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord mathnormal">O</span><span class="mopen">(</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span></em><strong>.</strong></li>
<li><strong>Condition:</strong> Works only on <strong>sorted arrays</strong>.</li>
</ul>
<hr />
<h3>Implementing Binary Search on Arduino</h3>
<p>To illustrate binary search, let’s start with a basic example on Arduino. Suppose we have a sorted array and we want to check if a given value exists within it.</p>
<h4>Example Code</h4>
<p>Let’s create a sorted array and a binary search function that returns the index of the target element or -1 if it’s not found.</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">int sortedArray[] = {2, 5, 7, 12, 15, 18, 21, 24, 27, 30};
int arraySize = sizeof(sortedArray) / sizeof(sortedArray[0]);

// Binary search function
int binarySearch(int array[], int size, int target) {
    int left = 0;
    int right = size - 1;
    
    while (left &lt;= right) {
        int mid = left + (right - left) / 2;

        // Check if target is at mid
        if (array[mid] == target) {
            return mid;
        }
        
        // If target is greater, ignore left half
        if (array[mid] &lt; target) {
            left = mid + 1;
        }
        // If target is smaller, ignore right half
        else {
            right = mid - 1;
        }
    }
    // Target is not present in array
    return -1;
}

void setup() {
    Serial.begin(9600);

    int target = 15; // Change this to test different values
    int result = binarySearch(sortedArray, arraySize, target);
    
    if (result != -1) {
        Serial.print(&quot;Element found at index: &quot;);
        Serial.println(result);
    } else {
        Serial.println(&quot;Element not found.&quot;);
    }
}

void loop() {
    // No need to do anything here
}</code></pre></pre>
</div>
<p>In this example:</p>
<ul>
<li>We define a sorted array <em>sortedArray</em>.</li>
<li><em>binarySearch()</em> function takes in the array, its size, and the target value.</li>
<li>If the target is found, it returns the index; otherwise, it returns <em>-1</em>.</li>
</ul>
<p>Upload the code to your Arduino, open the Serial Monitor, and check the output. You should see the index of the target if it exists.</p>
<hr />
<h3>Using Binary Search to Map Values on Arduino</h3>
<p>Now that we understand the basics of binary search, let’s look at a practical use case: <strong>mapping analog sensor readings to specific ranges or categories</strong>.</p>
<p>Suppose we have an analog sensor that provides varying readings from 0 to 1023, and we want to map these readings to certain ranges to make decisions. Binary search can quickly locate which range an analog reading belongs to, allowing the Arduino to respond based on this range.</p>
<h4>Example: Mapping Sensor Readings to Predefined Ranges</h4>
<p>Let’s say we have ranges defined as follows:</p>
<ul>
<li><strong>Low:</strong> 0 to 200</li>
<li><strong>Medium:</strong> 201 to 600</li>
<li><strong>High:</strong> 601 to 800</li>
<li><strong>Very High:</strong> 801 to 1023</li>
</ul>
<p>Using binary search, we can quickly find which range a reading falls into.</p>
<h4>Code Example for Mapping with Binary Search</h4>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="sticky top-9 md:top-[5.75rem]">
<div class="absolute bottom-0 right-2 flex h-9 items-center">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">// Define range boundaries
int boundaries[] = {200, 600, 800, 1023};
String categories[] = {&quot;Low&quot;, &quot;Medium&quot;, &quot;High&quot;, &quot;Very High&quot;};
int numCategories = sizeof(boundaries) / sizeof(boundaries[0]);

// Function to find the range index
int findRange(int value) {
    int left = 0;
    int right = numCategories - 1;
    
    while (left &lt;= right) {
        int mid = left + (right - left) / 2;

        // If the value is less than or equal to the boundary
        if (value &lt;= boundaries[mid]) { if (mid == 0 || value &gt; boundaries[mid - 1]) {
                return mid;
            }
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return -1; // If value is out of range
}

void setup() {
    Serial.begin(9600);
}

void loop() {
    int sensorValue = analogRead(A0); // Read sensor value from analog pin A0
    int rangeIndex = findRange(sensorValue);

    if (rangeIndex != -1) {
        Serial.print(&quot;Sensor Value: &quot;);
        Serial.print(sensorValue);
        Serial.print(&quot; - Category: &quot;);
        Serial.println(categories[rangeIndex]);
    } else {
        Serial.println(&quot;Value out of defined ranges.&quot;);
    }
    
    delay(1000); // Delay for readability in Serial Monitor
}</code></pre></pre>
</div>
</div>
</div>
<h3 class="overflow-y-auto p-4" dir="ltr"><strong>Explanation:</strong></h3>
</div>
<ol>
<li><strong>Range Boundaries:</strong> We define an array boundaries where each element represents the upper boundary of a range.</li>
<li><strong>Category Array:</strong> categories holds labels for each range.</li>
<li><strong>findRange Function:</strong> We use a modified binary search to quickly find which range the <em>sensorValue</em> belongs to. It checks if <em>sensorValue</em> is less than or equal to the midpoint boundary and returns the corresponding category.</li>
</ol>
<p>When you run this code, the Arduino reads an analog value from A0 every second, determines the category it falls into, and displays it on the Serial Monitor.</p>
<div class="box info  aligncenter" style="width:500px"><div class="box-inner-block"><i class="fa tie-shortcode-boxicon"></i>
			
<h3>Additional Tips</h3>
<ul>
<li><strong>Expandability:</strong> You can expand this concept to any number of ranges. Just adjust the boundaries and categories arrays accordingly.</li>
<li><strong>Accuracy:</strong> Be sure your boundaries array is sorted in ascending order; binary search depends on this for accuracy.</li>
</ul>

			</div></div>
<hr />
<h3>Conclusion</h3>
<p>Binary search is a powerful algorithm for quickly locating data in sorted arrays, and it’s especially useful in embedded systems where performance is key. In Arduino applications, binary search can be used effectively to categorize analog readings or even to manage larger datasets within the constraints of limited processing power. This approach allows us to make decisions based on data ranges efficiently and reliably.</p>
<p>Happy coding!</p>
<p>The post <a href="https://www.teachmemicro.com/binary-search-and-its-application-on-arduino/">Binary Search and Its Application on Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Arduino RS-485 Protocol Tutorial</title>
		<link>https://www.teachmemicro.com/arduino-rs-485-protocol-tutorial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arduino-rs-485-protocol-tutorial</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 21 Oct 2024 01:00:39 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7378</guid>

					<description><![CDATA[<p>RS-485 is a popular serial communication standard used in industrial control systems, automation, and other applications where long-distance communication is required. Unlike RS-232, RS-485 uses differential signaling, which makes it more robust to noise and interference, making it ideal for industrial environments. Moreover, RS-485 supports multi-device communication on the same bus, allowing for a master-slave &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/arduino-rs-485-protocol-tutorial/">Arduino RS-485 Protocol Tutorial</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="font-weight: 400;">RS-485 is a popular serial communication standard used in industrial control systems, automation, and other applications where long-distance communication is required. Unlike RS-232, RS-485 uses differential signaling, which makes it more robust to noise and interference, making it ideal for industrial environments. Moreover, RS-485 supports multi-device communication on the same bus, allowing for a master-slave or peer-to-peer communication model, with up to 32 devices typically supported.</span></p>
<p><span id="more-7378"></span></p>
<h3><b>Why Use RS-485?</b></h3>
<p><span style="font-weight: 400;">RS-485 is highly reliable for long-distance communication (up to 1.2 km at lower baud rates) and is often used in environments prone to electromagnetic interference (EMI), such as factories or industrial sites. It allows multiple devices to share a single bus, which is a major advantage in systems that require distributed control, such as sensors, actuators, and controllers communicating over the same wire.</span></p>
<h3><b>Using RS-485 with Arduino</b></h3>
<p><span style="font-weight: 400;">To establish RS-485 communication with an Arduino, you'll need an RS-485 module, such as the MAX485 or other similar transceiver modules. These modules convert TTL-level signals from the Arduino to RS-485 differential signals, enabling communication with other RS-485 devices.</span></p>
<p><span style="font-weight: 400;">Here's how you can wire and code an Arduino for RS-485 communication:</span></p>
<h4><b>Components Needed:</b></h4>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Arduino (any model like UNO, Nano, etc.)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">RS-485 Module (MAX485 or equivalent)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Jumper wires</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Power supply (optional)</span></li>
</ol>
<h4><b>RS-485 Pinout (Typical for MAX485):</b></h4>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>DI (Driver Input)</b><span style="font-weight: 400;">: Connects to Arduino's TX pin (transmit data).</span></li>
<li style="font-weight: 400;" aria-level="1"><b>RO (Receiver Output)</b><span style="font-weight: 400;">: Connects to Arduino's RX pin (receive data).</span></li>
<li style="font-weight: 400;" aria-level="1"><b>DE (Driver Enable)</b><span style="font-weight: 400;">: Used to switch between transmit and receive modes.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>RE (Receiver Enable)</b><span style="font-weight: 400;">: Also controls receive mode. Often tied with DE.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>A/B</b><span style="font-weight: 400;">: The differential data lines used for RS-485 communication.</span></li>
</ul>
<h4><b>Wiring Diagram:</b></h4>
<table>
<tbody>
<tr>
<td><b>Arduino Pin</b></td>
<td><b>RS-485 Module Pin</b></td>
</tr>
<tr>
<td><span style="font-weight: 400;">TX (Pin 1)</span></td>
<td><span style="font-weight: 400;">DI</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">RX (Pin 0)</span></td>
<td><span style="font-weight: 400;">RO</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Digital Pin 2</span></td>
<td><span style="font-weight: 400;">DE (Driver Enable)</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">Digital Pin 3</span></td>
<td><span style="font-weight: 400;">RE (Receiver Enable)</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">GND</span></td>
<td><span style="font-weight: 400;">GND</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">5V</span></td>
<td><span style="font-weight: 400;">VCC</span></td>
</tr>
<tr>
<td><span style="font-weight: 400;">A/B</span></td>
<td><span style="font-weight: 400;">A/B (RS-485 bus)</span></td>
</tr>
</tbody>
</table>
<p><img loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb.png" alt="Arduino RS-485 Tutorial" width="2685" height="1038" class="aligncenter wp-image-7379 size-full" srcset="https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb.png 2685w, https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb-300x116.png 300w, https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb-1024x396.png 1024w, https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb-768x297.png 768w, https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb-1536x594.png 1536w, https://www.teachmemicro.com/wp-content/uploads/2024/10/arduino-rs485_bb-2048x792.png 2048w" sizes="auto, (max-width: 2685px) 100vw, 2685px" /></p>
<p><span style="font-weight: 400;">For </span><b>multi-device</b><span style="font-weight: 400;"> communication, connect all the A terminals together, and all the B terminals together. Ensure termination resistors (typically 120 ohms) are placed between the A and B lines at the bus ends to reduce signal reflections.</span></p>
<h3><b>Example Code</b></h3>
<p><span style="font-weight: 400;">Here is an example sketch to demonstrate sending and receiving data using RS-485:</span></p>
<h4><b>Transmitter Code (Master):</b></h4>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define DE_PIN 2  // Define Driver Enable pin
#define RE_PIN 3  // Define Receiver Enable pin

void setup() {
  pinMode(DE_PIN, OUTPUT);
  pinMode(RE_PIN, OUTPUT);

  // Enable RS-485 transmitter
  digitalWrite(DE_PIN, HIGH);
  digitalWrite(RE_PIN, HIGH);  // RE tied with DE to switch between TX and RX

  Serial.begin(9600); // Start Serial communication at 9600 baud rate
}


void loop() {
  // Transmit message every 1 second
  const char message[] = &quot;Hello from Master&quot;;

  // Enable transmission mode
  digitalWrite(DE_PIN, HIGH);
  Serial.write(message, sizeof(message) - 1);  // Send data over RS-485
  delay(100);  // Wait for data to finish sending
  digitalWrite(DE_PIN, LOW);  // Switch to receiving mode

  delay(1000);  // Wait before next message
}</code></pre></pre>
</div>
<h4><b>Receiver Code (Slave):</b></h4>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define DE_PIN 2  // Define Driver Enable pin
#define RE_PIN 3  // Define Receiver Enable pin

void setup() {
  pinMode(DE_PIN, OUTPUT);
  pinMode(RE_PIN, OUTPUT);
  
  // Enable RS-485 receiver
  digitalWrite(DE_PIN, LOW);
  digitalWrite(RE_PIN, LOW);  // RE tied with DE for receiving mode

  Serial.begin(9600); // Start Serial communication at 9600 baud rate
}


void loop() {
  // Check if data is available to read
  if (Serial.available()) {
    while (Serial.available()) {
      char received = Serial.read();  // Read received data byte by byte
      Serial.print(received);         // Print received data to Serial Monitor
    }
    Serial.println();  // Add a newline after message is received
  }
}</code></pre></pre>
</div>
<h3><b>Explanation:</b></h3>
<ol>
<li style="font-weight: 400;" aria-level="1"><b>Transmitting (Master)</b><span style="font-weight: 400;">:</span>
<ul>
<li style="font-weight: 400;" aria-level="2"><span style="font-weight: 400;">The </span><span style="font-weight: 400;">DE_PIN</span><span style="font-weight: 400;"> and </span><span style="font-weight: 400;">RE_PIN</span><span style="font-weight: 400;"> are set high to enable the transmit mode.</span></li>
<li style="font-weight: 400;" aria-level="2"><span style="font-weight: 400;">The message is sent using </span><span style="font-weight: 400;">Serial.write()</span><span style="font-weight: 400;">, and then the DE pin is set low to switch back to receive mode after transmission.</span></li>
</ul>
</li>
<li style="font-weight: 400;" aria-level="1"><b>Receiving (Slave)</b><span style="font-weight: 400;">:</span>
<ul>
<li style="font-weight: 400;" aria-level="2"><span style="font-weight: 400;">The DE and RE pins are kept low to enable the receiver mode.</span></li>
<li style="font-weight: 400;" aria-level="2"><span style="font-weight: 400;">The slave reads incoming data using </span><span style="font-weight: 400;">Serial.read()</span><span style="font-weight: 400;"> and prints it to the Serial Monitor.</span></li>
</ul>
</li>
</ol>
<h3>Why Are Termination Resistors Needed?</h3>
<div class="box info  aligncenter" style="width:500px"><div class="box-inner-block"><i class="fa tie-shortcode-boxicon"></i>
			
If you are using the RS485 to TTL module shown in the images above, you don't need terminating resistors as they are already mounted on the modules!</p>

			</div></div>
<p>In an RS-485 bus, the communication lines (A and B) form a transmission line. Without termination, the signals transmitted through the A and B lines can reflect back when they reach the end of the line, causing interference and data corruption. Termination resistors, typically 120 ohms, are placed at each end of the bus to absorb the signal energy and prevent reflections, ensuring a clean and stable signal.</p>
<h3>When Do You Need Termination Resistors?</h3>
<ul>
<li><strong>Long Distances</strong>: If your RS-485 network spans a considerable length (typically more than 10 meters or 30 feet), termination resistors are essential to maintain data integrity.</li>
<li><strong>Higher Baud Rates</strong>: For higher communication speeds (e.g., 115200 baud or more), the transmission time is shorter, and reflections can cause significant issues without termination.</li>
<li><strong>Multiple Devices</strong>: If you have multiple devices on the RS-485 bus, the combined signal reflections from the un-terminated ends could affect the communication quality.</li>
</ul>
<h3>When Can You Avoid Termination Resistors?</h3>
<ul>
<li><strong>Short Distances</strong>: In very short distances (under a few meters), termination resistors may not be strictly necessary since the signal reflections will be negligible.</li>
<li><strong>Lower Baud Rates</strong>: If your baud rate is relatively low (e.g., 9600 baud or less) and the cable distance is short, the communication may work reliably without termination resistors.</li>
</ul>
<h3>Placement of Termination Resistors</h3>
<ul>
<li>Place <strong>one 120-ohm resistor between A and B</strong> at each end of the RS-485 bus.</li>
<li>If you only have two devices (one transmitter and one receiver), place a resistor at each device. For multi-node setups, place resistors at the two devices that are physically at the ends of the bus, not at each device in between.</li>
</ul>
<h3><b>Error Handling</b></h3>
<p><span style="font-weight: 400;">In a real-world application, you might need to implement error checking, such as:</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Timeout mechanisms</b><span style="font-weight: 400;"> for checking if a message has been lost.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>CRC (Cyclic Redundancy Check)</b><span style="font-weight: 400;"> or </span><b>Checksum</b><span style="font-weight: 400;"> for verifying data integrity.</span></li>
</ul>
<h3><b>Conclusion</b></h3>
<p><span style="font-weight: 400;">RS-485 is an ideal choice for reliable communication in harsh environments where long distances are involved. Using Arduino with RS-485 modules allows you to create robust communication networks between multiple devices like sensors, actuators, and controllers. The example code and setup provided demonstrate how to easily get started with RS-485 communication on the Arduino platform, offering a practical solution for industrial automation or distributed control systems.</span></p>
<p>The post <a href="https://www.teachmemicro.com/arduino-rs-485-protocol-tutorial/">Arduino RS-485 Protocol Tutorial</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Creating Tones with Arduino</title>
		<link>https://www.teachmemicro.com/creating-tones-with-arduino/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=creating-tones-with-arduino</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 18 Oct 2024 01:00:26 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7375</guid>

					<description><![CDATA[<p>One of the fun and engaging projects with Arduino is creating tones using a piezo buzzer. You can generate simple beeps, melodic tunes, or even popular themes like the Super Mario theme song. In this tutorial, we'll explore how to generate tones, work with melodies, and build a simple sound generator using Arduino. Materials Needed: &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/creating-tones-with-arduino/">Creating Tones with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="font-weight: 400;">One of the fun and engaging projects with Arduino is creating tones using a piezo buzzer. You can generate simple beeps, melodic tunes, or even popular themes like the </span><b>Super Mario</b><span style="font-weight: 400;"> theme song. In this tutorial, we'll explore how to generate tones, work with melodies, and build a simple sound generator using Arduino.</span></p>
<p><span id="more-7375"></span></p>
<h4><b>Materials Needed:</b></h4>
<div class="checklist tie-list-shortcode">
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Arduino board (Uno, Nano, etc.)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Piezo buzzer or speaker</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Jumper wires</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Breadboard (optional)</span></li>
</ul>
</div>
<h4><b>What is a Piezo Buzzer?</b></h4>
<p><span style="font-weight: 400;">A </span><b>piezo buzzer</b><span style="font-weight: 400;"> is an electronic component that produces sound based on the voltage signal it receives. When used with an Arduino, it can produce various tones by sending different frequencies through the </span><i><span style="font-weight: 400;">tone()</span></i><span style="font-weight: 400;"> function.</span></p>
<h4><b>Wiring Your Arduino for Sound</b></h4>
<p><span style="font-weight: 400;">First, connect the piezo buzzer to your Arduino:</span></p>
<ol>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Connect one leg of the piezo buzzer to </span><b>Pin 8</b><span style="font-weight: 400;"> of your Arduino (or any other digital pin).</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Connect the other leg to the </span><b>ground (GND)</b><span style="font-weight: 400;"> pin.</span></li>
</ol>
<p><span style="font-weight: 400;">You can optionally use a breadboard for easy connections, but directly connecting the piezo buzzer to the Arduino works as well.</span></p>
<h4><b>Understanding the </b><b>tone()</b><b> Function</b></h4>
<p><span style="font-weight: 400;">The </span><i><span style="font-weight: 400;">tone()</span></i><span style="font-weight: 400;"> function is the key to producing sounds with Arduino. Its basic syntax is:</span></p>
<p><span style="font-weight: 400;">tone(pin, frequency, duration);</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">pin</span><span style="font-weight: 400;">: The Arduino pin where the piezo buzzer is connected.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">frequency</span><span style="font-weight: 400;">: The frequency of the tone in Hertz (Hz), which determines the pitch.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">duration</span><span style="font-weight: 400;">: (Optional) The length of time the tone plays, in milliseconds (ms). If omitted, the tone will play indefinitely.</span></li>
</ul>
<p><span style="font-weight: 400;">Example:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">tone(8, 440, 500); // Play a 440Hz tone (A4) for 500 milliseconds</code></pre></pre>
</div>
<h4><b>Simple Tone Example</b></h4>
<p><span style="font-weight: 400;">Let's start with a basic tone example that plays a middle C note (261 Hz) for 1 second:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">void setup() {
  tone(8, 261, 1000); // Plays middle C (261 Hz) for 1 second
}

void loop() {
  // No code needed here
}</code></pre></pre>
</div>
<p><span style="font-weight: 400;">This will make your piezo buzzer produce a single tone.</span></p>
<h3><b>Creating Melodies</b></h3>
<p><span style="font-weight: 400;">To make things more interesting, you can string multiple tones together to form melodies. Let's create a simple melody using an array of frequencies and durations.</span></p>
<h4><b>Example: Playing a Simple Melody</b></h4>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">int melody[] = {
  262, 294, 330, 349, 392, 440, 494, 523  // C4, D4, E4, F4, G4, A4, B4, C5
};

int noteDurations[] = {
  500, 500, 500, 500, 500, 500, 500, 500 // Duration of each note
};


void setup() {
  for (int i = 0; i &lt; 8; i++) {
    int noteDuration = noteDurations[i];
    tone(8, melody[i], noteDuration);
    delay(noteDuration + 100); // Pause between notes
  }
}


void loop() {
  // No code needed here
}</code></pre></pre>
</div>
<p><span style="font-weight: 400;">This simple melody plays the </span><b>C major scale</b><span style="font-weight: 400;">, with each note lasting 500 ms.</span></p>
<h3><b>Example: Super Mario Theme</b></h3>
<p><span style="font-weight: 400;">Now let's tackle something more exciting — a portion of the </span><b>Super Mario Bros. Theme</b><span style="font-weight: 400;">! Below is an Arduino sketch to play the first few notes of the iconic melody.</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define NOTE_E7 2637
#define NOTE_E6 1319
#define NOTE_FS6 1479
#define NOTE_GS6 1568
#define NOTE_A6 1760
#define NOTE_B6 1976
#define NOTE_E5 659


int melody[] = {
  NOTE_E7, NOTE_E7, 0, NOTE_E7,
  0, NOTE_C7, NOTE_E7, 0,
  NOTE_G7, 0, 0, 0,
  NOTE_G6, 0, 0, 0
};


int noteDurations[] = {
  125, 125, 125, 125,
  125, 125, 125, 125,
  125, 125, 125, 125,
  125, 125, 125, 125
};

void setup() {
  for (int i = 0; i &lt; 16; i++) {
    int noteDuration = noteDurations[i];
    if (melody[i] == 0) {
      delay(noteDuration); // Rest for the duration of the note
    } else {
      tone(8, melody[i], noteDuration);
      delay(noteDuration + 50); // Add a slight pause between notes
    }
  }
}

void loop() {
  // No code needed here
}</code></pre></pre>
</div>
<h3><b>Breaking Down the Super Mario Code:</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Notes</b><span style="font-weight: 400;">: We define several musical notes using their frequencies. These are stored in </span><span style="font-weight: 400;">melody[]</span><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Durations</b><span style="font-weight: 400;">: Each note is given a specific duration, stored in </span><span style="font-weight: 400;">noteDurations[]</span><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Rest</b><span style="font-weight: 400;">: A </span><span style="font-weight: 400;">0</span><span style="font-weight: 400;"> in the melody array signifies a rest, meaning no sound will be played for the duration of that note.</span></li>
</ul>
<p><span style="font-weight: 400;">Here are two more examples: the </span><b>Star Wars Theme</b><span style="font-weight: 400;"> and </span><b>Harry Potter Theme</b><span style="font-weight: 400;">. Let's dive into each one and how to implement them with Arduino!</span></p>
<h3><b>Star Wars Theme</b></h3>
<p><span style="font-weight: 400;">Below is an Arduino sketch that plays a portion of the </span><b>Star Wars Theme</b><span style="font-weight: 400;">:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define NOTE_D5 587
#define NOTE_E5 659
#define NOTE_F5 698
#define NOTE_G5 784
#define NOTE_A5 880

int melody[] = {
  NOTE_A4, NOTE_A4, NOTE_A4, NOTE_F5, NOTE_C6, 
  NOTE_A5, NOTE_F5, NOTE_C6, NOTE_A5,
  0, NOTE_E6, NOTE_E6, NOTE_E6, NOTE_F6, NOTE_C6, 
  NOTE_G5, NOTE_F5, NOTE_C6, NOTE_A5
};


int noteDurations[] = {
  500, 500, 500, 350, 150, 
  500, 350, 150, 1000, 
  500, 500, 500, 350, 150, 
  500, 350, 150, 1000
};


void setup() {
  for (int i = 0; i &lt; 18; i++) {
    int noteDuration = noteDurations[i];
    if (melody[i] == 0) {
      delay(noteDuration); // Pause for rests
    } else {
      tone(8, melody[i], noteDuration);
      delay(noteDuration + 50); // Pause between notes
    }
  }
}

void loop() {
  // No code needed here
}</code></pre></pre>
</div>
<h3><b>Breaking Down the Star Wars Code:</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Notes</b><span style="font-weight: 400;">: Frequencies of the notes in the Star Wars theme are defined in </span><span style="font-weight: 400;">melody[]</span><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Durations</b><span style="font-weight: 400;">: Each note’s duration is stored in </span><span style="font-weight: 400;">noteDurations[]</span><span style="font-weight: 400;">. A longer delay is used for more dramatic pauses in the theme.</span></li>
</ul>
<h3><b>Harry Potter Theme</b></h3>
<p><span style="font-weight: 400;">Next, here’s the </span><b>Harry Potter Theme</b><span style="font-weight: 400;">:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#define NOTE_D4 293
#define NOTE_G4 392
#define NOTE_AS4 466
#define NOTE_A4 440
#define NOTE_F4 349
#define NOTE_C5 523
#define NOTE_G5 784

int melody[] = {
  NOTE_D4, NOTE_G4, NOTE_AS4, NOTE_A4, NOTE_G4, NOTE_D5, NOTE_C5, NOTE_A4, 
  NOTE_G4, NOTE_AS4, NOTE_A4, NOTE_F4, NOTE_G4, 0
};


int noteDurations[] = {
  500, 500, 500, 350, 150, 
  500, 500, 500, 500, 500, 
  350, 150, 1000, 500
};

void setup() {
  for (int i = 0; i &lt; 14; i++) {
    int noteDuration = noteDurations[i];
    if (melody[i] == 0) {
      delay(noteDuration); // Rest for pauses
    } else {
      tone(8, melody[i], noteDuration);
      delay(noteDuration + 50); // Pause between notes
    }
  }
}

void loop() {
  // No code needed here
}</code></pre></pre>
</div>
<h3><b>Breaking Down the Harry Potter Code:</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Notes</b><span style="font-weight: 400;">: Frequencies of the Harry Potter theme’s notes are defined in </span><span style="font-weight: 400;">melody[]</span><span style="font-weight: 400;">.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Durations</b><span style="font-weight: 400;">: Each note’s duration is defined in </span><span style="font-weight: 400;">noteDurations[]</span><span style="font-weight: 400;">. A </span><span style="font-weight: 400;">0</span><span style="font-weight: 400;"> is used to create rests where there is silence.</span></li>
</ul>
<h3><b>Conclusion</b></h3>
<p><span style="font-weight: 400;">By using the </span><span style="font-weight: 400;">tone()</span><span style="font-weight: 400;"> function and controlling the timing, you can create simple tones, scales, and even popular theme songs with your Arduino and a piezo buzzer. Experiment with different melodies, note lengths, and rhythms to make your projects sound fun and dynamic!</span></p>
<h3><b>Next Steps</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Try adding buttons to trigger specific melodies.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Use potentiometers to change the frequency dynamically.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Expand the Super Mario theme or create your own tunes!</span></li>
</ul>
<p><span style="font-weight: 400;">Have fun making music with your Arduino!</span></p>
<p>The post <a href="https://www.teachmemicro.com/creating-tones-with-arduino/">Creating Tones with Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Converting Between Data Types in Arduino</title>
		<link>https://www.teachmemicro.com/converting-between-data-types-in-arduino/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=converting-between-data-types-in-arduino</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 18 Oct 2024 01:00:00 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7421</guid>

					<description><![CDATA[<p>When writing code for Arduino, you'll often need to convert between different data types. This guide will show you how to easily convert between the most common data types. We'll break it down with clear examples and easy-to-read tables to make it simple to follow. Why Convert Data Types? Sometimes, the data you're working with &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/converting-between-data-types-in-arduino/">Converting Between Data Types in Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>When writing code for Arduino, you'll often need to convert between different data types. This guide will show you how to easily convert between the most common data types. We'll break it down with clear examples and easy-to-read tables to make it simple to follow.</p>
<hr />
<h3><strong>Why Convert Data Types?</strong></h3>
<p>Sometimes, the data you're working with isn't in the format you need. For example:</p>
<div class="checklist tie-list-shortcode">
<ul>
<li>You may get a value as a <em>String</em> but need it as an <em>int</em> for math.</li>
<li>You may have a <em>float</em> value (decimal number) that needs to be shown as a <em>String</em> on an LCD.</li>
</ul>
</div>
<p>Understanding how to convert between types ensures your Arduino program works smoothly.</p>
<hr />
<h3><strong>Common Data Types in Arduino</strong></h3>
<p>Before we dive into conversions, here’s a quick overview of the most common data types you'll encounter:</p>
<table>
<thead>
<tr>
<th>Data Type</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td>int</td>
<td>A whole number (no decimals)</td>
<td>int x = 123;</td>
</tr>
<tr>
<td>float</td>
<td>A number with decimals</td>
<td>float y = 12.34;</td>
</tr>
<tr>
<td>char</td>
<td>A single character (letter or symbol)</td>
<td>char z = 'A';</td>
</tr>
<tr>
<td>String</td>
<td>A string of characters (words, numbers)</td>
<td>String str = "Hello";</td>
</tr>
<tr>
<td>bool</td>
<td>A true/false value</td>
<td>bool flag = true;</td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Converting Between Data Types</strong></h3>
<p>Now, let's explore the most common conversions you'll need.</p>
<hr />
<h4><strong>a. Converting String to int</strong></h4>
<p>When working with user input or data from sensors, you'll often have numbers as <em>String</em>, but you might need them as int to perform calculations.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">String strValue = &quot;123&quot;; 
int intValue = strValue.toInt();</code></pre></pre>
</div>
</div>
</div>
<p>In the above example, "123" is a <em>String</em>, and <em>toInt()</em> converts it to an integer.</p>
<hr />
<h4><strong>b. Converting int to String</strong></h4>
<p>You might want to display an integer value as a <em>String</em>, like showing sensor data on an LCD.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">int intValue = 123; 
String strValue = String(intValue);</code></pre></pre>
</div>
</div>
</div>
<p>Here, <em>String(intValue)</em> converts the integer to a <em>String</em>.</p>
<hr />
<h4><strong>c. Converting float to String</strong></h4>
<p>To convert a decimal number to a <em>String</em>, you can use the <em>String()</em> function.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">float floatValue = 12.34; 
String strValue = String(floatValue, 2); // &#039;2&#039; defines decimal places</code></pre></pre>
</div>
</div>
</div>
<p>In this example, <em>String(floatValue, 2) </em>converts the float to a <em>String</em> with 2 decimal places.</p>
<hr />
<h4><strong>d. Converting String to float</strong></h4>
<p>If you have a number in a <em>String</em> but need it as a decimal number (float), use<em> toFloat().</em></p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">String strValue = &quot;12.34&quot;;
float floatValue = strValue.toFloat();</code></pre></pre>
</div>
</div>
</div>
<p>The <em>toFloat()</em> function converts the string to a float.</p>
<hr />
<h4><strong>e. Converting char to String</strong></h4>
<p>You may have single characters (char) and want to convert them into a <em>String</em> to work with.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">char letter = &#039;A&#039;; 
String strValue = String(letter);</code></pre></pre>
</div>
</div>
</div>
<hr />
<h4><strong>f. Converting String to char</strong></h4>
<p>If you need to extract a char from a <em>String</em>, use the <em>charAt()</em> function.</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">String strValue = &quot;Hello&quot;; 
char firstLetter = strValue.charAt(0); // Gets the first letter &#039;H&#039;</code></pre></pre>
</div>
</div>
</div>
<hr />
<h4><strong>g. Converting int to char</strong></h4>
<p>To convert an integer (from 0 to 9) into its character representation, use:</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">int num = 5; 
char charValue = &#039;0&#039; + num; // Converts 5 into the character &#039;5&#039;</code></pre></pre>
</div>
</div>
</div>
<hr />
<h4><strong>h. Converting char to int</strong></h4>
<p>To get the numeric value of a character, subtract '0':</p>
<div class="contain-inline-size rounded-md border-[0.5px] border-token-border-medium relative bg-token-sidebar-surface-primary dark:bg-gray-950">
<div class="overflow-y-auto p-4" dir="ltr">
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">char charValue = &#039;5&#039;; 
int intValue = charValue - &#039;0&#039;; // Converts &#039;5&#039; into the number 5</code></pre></pre>
</div>
</div>
</div>
<hr />
<h3>4. <strong>Conversion Table: Quick Reference</strong></h3>
<table>
<thead>
<tr>
<th>From</th>
<th>To</th>
<th>Method or Function</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><em>String</em></td>
<td><em>int</em></td>
<td><em>toInt()</em></td>
<td><em>strValue.toInt()</em></td>
</tr>
<tr>
<td><em>int</em></td>
<td><em>String</em></td>
<td><em>String()</em></td>
<td><em>String(intValue)</em></td>
</tr>
<tr>
<td><em>float</em></td>
<td><em>String</em></td>
<td><em>String(variable, decimal)</em></td>
<td><em>String(floatValue, 2)</em></td>
</tr>
<tr>
<td><em>String</em></td>
<td><em>float</em></td>
<td><em>.toFloat()</em></td>
<td><em>strValue.toFloat()</em></td>
</tr>
<tr>
<td><em>char</em></td>
<td><em>String</em></td>
<td><em>String()</em></td>
<td><em>String(charValue)</em></td>
</tr>
<tr>
<td><em>String</em></td>
<td><em>char</em></td>
<td><em>.charAt(index)</em></td>
<td><em>strValue.charAt(0)</em></td>
</tr>
<tr>
<td><em>int</em></td>
<td><em>char</em></td>
<td><em>'0' + variable</em></td>
<td><em>'0' + intValue</em></td>
</tr>
<tr>
<td><em>char</em></td>
<td><em>int</em></td>
<td><em>variable - '0'</em></td>
<td><em>charValue - '0'</em></td>
</tr>
</tbody>
</table>
<hr />
<h3><strong>Conclusion</strong></h3>
<p>By mastering these basic conversions, you can manipulate data effectively in your Arduino programs. Whether you're converting user input, sensor data, or simply formatting numbers for display, these functions will come in handy. Keep this guide as a reference, and soon these conversions will become second nature to you!</p>
<hr />
<p>I hope this tutorial helped simplify data type conversions for you! If you have more questions or suggestions, feel free to drop a comment on the blog.</p>
<p>The post <a href="https://www.teachmemicro.com/converting-between-data-types-in-arduino/">Converting Between Data Types in Arduino</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Arduino Interfacing with MLX90614 (GY-906) Sensor</title>
		<link>https://www.teachmemicro.com/arduino-interfacing-mlx90614-gy906-sensor/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arduino-interfacing-mlx90614-gy906-sensor</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Thu, 03 Oct 2024 01:00:59 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7336</guid>

					<description><![CDATA[<p>The MLX90614 is a really cool infrared thermometer sensor that can measure temperature without even touching an object. It works by detecting infrared radiation (heat) emitted by an object and converting it into a temperature reading. This makes it perfect for projects where you want to measure temperature from a distance, like reading the temperature &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/arduino-interfacing-mlx90614-gy906-sensor/">Arduino Interfacing with MLX90614 (GY-906) Sensor</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="font-weight: 400;">The MLX90614 is a really cool infrared thermometer sensor that can measure temperature without even touching an object. It works by detecting infrared radiation (heat) emitted by an object and converting it into a temperature reading. This makes it perfect for projects where you want to measure temperature from a distance, like reading the temperature of a hot surface, or even someone’s forehead.</span></p>
<p><span style="font-weight: 400;">In this article, I’ll show you how to use the MLX90614 with an Arduino. It’s a super simple setup and a great sensor to add to your toolkit.</span></p>
<h3><b>What You’ll Need</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Arduino board (like an Uno)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">MLX90614 sensor</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">16x2 LCD display</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Jumper wires</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Breadboard (optional)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">A computer with the Arduino IDE installed</span></li>
</ul>
<h3><b>How the MLX90614 Works</b></h3>
<p><span style="font-weight: 400;">The MLX90614 has two types of temperature readings:</span></p>
<ol>
<li style="font-weight: 400;" aria-level="1"><b>Object Temperature</b><span style="font-weight: 400;">: This is the temperature of the object you're pointing the sensor at.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Ambient Temperature</b><span style="font-weight: 400;">: This is the temperature of the surrounding air.</span></li>
</ol>
<p><span style="font-weight: 400;">The sensor communicates with the Arduino using the I2C protocol. I2C is a simple way for devices to communicate by using just two wires: </span><b>SDA</b><span style="font-weight: 400;"> (data line) and </span><b>SCL</b><span style="font-weight: 400;"> (clock line). The MLX90614 uses these to send temperature data to the Arduino.</span></p>
<h3><b>Wiring the MLX90614 to the Arduino</b></h3>
<p><span style="font-weight: 400;">First, let’s wire it up. The MLX90614 has four pins:</span></p>
<ol>
<li style="font-weight: 400;" aria-level="1"><b>VCC</b><span style="font-weight: 400;">: Power (3.3V or 5V)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>GND</b><span style="font-weight: 400;">: Ground</span></li>
<li style="font-weight: 400;" aria-level="1"><b>SDA</b><span style="font-weight: 400;">: Data line</span></li>
<li style="font-weight: 400;" aria-level="1"><b>SCL</b><span style="font-weight: 400;">: Clock line</span></li>
</ol>
<p><span style="font-weight: 400;">Here’s how to connect it to the Arduino:</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>VCC</b><span style="font-weight: 400;"> to the 3.3V (or 5V) pin on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>GND</b><span style="font-weight: 400;"> to GND on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>SDA</b><span style="font-weight: 400;"> to A4 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>SCL</b><span style="font-weight: 400;"> to A5 on the Arduino</span></li>
</ul>
<p><img loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_bb-1024x734.png" alt="Arduino MLX90614 " width="618" height="443" class="aligncenter wp-image-7338 size-large" srcset="https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_bb-1024x734.png 1024w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_bb-300x215.png 300w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_bb-768x550.png 768w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_bb.png 1164w" sizes="auto, (max-width: 618px) 100vw, 618px" /></p>
<p><span style="font-weight: 400;">Make sure everything is connected securely. Now let’s move on to the code.</span></p>
<h3><b>Writing the Code</b></h3>
<p><span style="font-weight: 400;">We’ll use the </span><b>Adafruit MLX90614 library</b><span style="font-weight: 400;"> to make reading temperatures easy. You can install this library in the Arduino IDE by going to </span><b>Sketch &gt; Include Library &gt; Manage Libraries</b><span style="font-weight: 400;">, then search for “Adafruit MLX90614” and install it.</span></p>
<p><span style="font-weight: 400;">Here’s a simple code to read and print the temperature:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;Wire.h&gt;
#include &lt;Adafruit_MLX90614.h&gt;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

void setup() {
  Serial.begin(9600);
  mlx.begin();
}

void loop() {
  Serial.print(&quot;Ambient Temp = &quot;);
  Serial.print(mlx.readAmbientTempC());
  Serial.print(&quot; °C\tObject Temp = &quot;);
  Serial.print(mlx.readObjectTempC());
  Serial.println(&quot; °C&quot;);

  delay(1000); // Read every second
}</code></pre></pre>
</div>
<h3><b>How the Code Works</b></h3>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>Wire.h</b><span style="font-weight: 400;"> is the library that handles I2C communication.</span></li>
<li style="font-weight: 400;" aria-level="1"><b>Adafruit_MLX90614.h</b><span style="font-weight: 400;"> is the library that makes interacting with the sensor easy.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">We create an object called </span><span style="font-weight: 400;">mlx</span><span style="font-weight: 400;"> to represent the sensor.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">In the </span><span style="font-weight: 400;">setup()</span><span style="font-weight: 400;">, we start communication with the sensor using </span><span style="font-weight: 400;">mlx.begin()</span><span style="font-weight: 400;"> and start the serial monitor with </span><span style="font-weight: 400;">Serial.begin(9600)</span><span style="font-weight: 400;"> so we can see the temperature readings.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">In the </span><span style="font-weight: 400;">loop()</span><span style="font-weight: 400;">, we read both the ambient temperature (</span><span style="font-weight: 400;">mlx.readAmbientTempC()</span><span style="font-weight: 400;">) and the object temperature (</span><span style="font-weight: 400;">mlx.readObjectTempC()</span><span style="font-weight: 400;">). These are printed to the serial monitor every second.</span></li>
</ul>
<h3><b>Adding a 16x2 LCD to Display Temperature</b></h3>
<p><span style="font-weight: 400;">Now, let's take it a step further by displaying the temperature readings on a 16x2 LCD. The LCD will show both the ambient and object temperatures in real-time.</span></p>
<h4><b>What You'll Need</b></h4>
<ul>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">A 16x2 LCD display</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">A potentiometer (for contrast adjustment)</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">Jumper wires</span></li>
</ul>
<h4><b>Wiring the LCD to the Arduino</b></h4>
<p><span style="font-weight: 400;">A 16x2 LCD typically has 16 pins. Here’s how to connect it:</span></p>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>VSS</b><span style="font-weight: 400;"> to GND</span></li>
<li style="font-weight: 400;" aria-level="1"><b>VDD</b><span style="font-weight: 400;"> to 5V</span></li>
<li style="font-weight: 400;" aria-level="1"><b>VO</b><span style="font-weight: 400;"> to the middle pin of the potentiometer (for adjusting contrast)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>RS</b><span style="font-weight: 400;"> to Pin 12 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>RW</b><span style="font-weight: 400;"> to GND</span></li>
<li style="font-weight: 400;" aria-level="1"><b>E</b><span style="font-weight: 400;"> to Pin 11 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>D4</b><span style="font-weight: 400;"> to Pin 5 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>D5</b><span style="font-weight: 400;"> to Pin 4 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>D6</b><span style="font-weight: 400;"> to Pin 3 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>D7</b><span style="font-weight: 400;"> to Pin 2 on the Arduino</span></li>
<li style="font-weight: 400;" aria-level="1"><b>A</b><span style="font-weight: 400;"> (Anode) to 5V (for the LCD backlight)</span></li>
<li style="font-weight: 400;" aria-level="1"><b>K</b><span style="font-weight: 400;"> (Cathode) to GND</span></li>
</ul>
<p><img loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-1024x566.png" alt="Arduino MLX90614 with LCD" width="618" height="342" class="wp-image-7339 size-large aligncenter" srcset="https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-1024x566.png 1024w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-300x166.png 300w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-768x424.png 768w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-1536x849.png 1536w, https://www.teachmemicro.com/wp-content/uploads/2024/10/Arduino-MLX90614_LCD_16x2-2048x1132.png 2048w" sizes="auto, (max-width: 618px) 100vw, 618px" /></p>
<h4><b>Updating the Code to Include the LCD</b></h4>
<p><span style="font-weight: 400;">You’ll also need the </span><b>LiquidCrystal</b><span style="font-weight: 400;"> library, which is built into the Arduino IDE, so no need to install anything. Here’s the updated code that displays the temperature on the LCD:</span></p>
<p>&nbsp;</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;Wire.h&gt;
#include &lt;Adafruit_MLX90614.h&gt;
#include &lt;LiquidCrystal.h&gt;

Adafruit_MLX90614 mlx = Adafruit_MLX90614();
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);  // Pins for the LCD

void setup() {
  Serial.begin(9600);
  mlx.begin();

  // Initialize the LCD and set the size (16 columns, 2 rows)
  lcd.begin(16, 2);
  lcd.print(&quot;Temp Monitor&quot;);  // Display a title on the LCD
  delay(2000);                // Wait for 2 seconds
  lcd.clear();                // Clear the display
}


void loop() {
  float ambientTemp = mlx.readAmbientTempC();
  float objectTemp = mlx.readObjectTempC();

  // Print to Serial Monitor
  Serial.print(&quot;Ambient Temp = &quot;);
  Serial.print(ambientTemp);
  Serial.print(&quot; °C\tObject Temp = &quot;);
  Serial.print(objectTemp);
  Serial.println(&quot; °C&quot;);

  // Display on LCD
  lcd.setCursor(0, 0);  // Set cursor to first row
  lcd.print(&quot;Amb: &quot;);
  lcd.print(ambientTemp);
  lcd.print(&quot; C&quot;);

  lcd.setCursor(0, 1);  // Set cursor to second row
  lcd.print(&quot;Obj: &quot;);
  lcd.print(objectTemp);
  lcd.print(&quot; C&quot;);

  delay(1000);  // Update every second
}</code></pre></pre>
</div>
<h4><b>How the LCD Code Works</b></h4>
<ul>
<li style="font-weight: 400;" aria-level="1"><b>LiquidCrystal lcd(12, 11, 5, 4, 3, 2)</b><span style="font-weight: 400;"> sets up the LCD with the correct pin connections.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">In the </span><span style="font-weight: 400;">setup()</span><span style="font-weight: 400;">, we initialize the LCD using </span><span style="font-weight: 400;">lcd.begin(16, 2)</span><span style="font-weight: 400;"> to tell it that we’re using a 16x2 display.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">We use </span><span style="font-weight: 400;">lcd.print()</span><span style="font-weight: 400;"> to write the temperature readings to the display.</span></li>
<li style="font-weight: 400;" aria-level="1"><span style="font-weight: 400;">The </span><span style="font-weight: 400;">lcd.setCursor()</span><span style="font-weight: 400;"> function positions the text. For example, </span><span style="font-weight: 400;">lcd.setCursor(0, 0)</span><span style="font-weight: 400;"> places the text at the start of the first row, and </span><span style="font-weight: 400;">lcd.setCursor(0, 1)</span><span style="font-weight: 400;"> moves it to the start of the second row.</span></li>
</ul>
<h3><b>Uploading the Code and Testing</b></h3>
<p><span style="font-weight: 400;">Once you've uploaded this code, you should see the ambient and object temperatures displayed on the 16x2 LCD. The Serial Monitor will also continue printing the temperatures, so you can check both if you like.</span></p>
<h3><b>Conclusion</b></h3>
<p><span style="font-weight: 400;">With the MLX90614 sensor and an Arduino, you can easily measure temperatures from a distance. Adding a 16x2 LCD makes it even more convenient, as you can display the readings without needing a computer or serial monitor. This combination can be useful for temperature monitoring projects, from environmental sensors to non-contact thermometers.</span></p>
<p><span style="font-weight: 400;">Now you have a guide on how to read temperatures with the MLX90614 and display them on a 16x2 LCD! Let me know if you want to add more to it.</span></p>
<p>&nbsp;</p>
<p>The post <a href="https://www.teachmemicro.com/arduino-interfacing-mlx90614-gy906-sensor/">Arduino Interfacing with MLX90614 (GY-906) Sensor</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Implementing PID for a Line Follower Robot</title>
		<link>https://www.teachmemicro.com/implementing-pid-for-a-line-follower-robot/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=implementing-pid-for-a-line-follower-robot</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 17 Jul 2024 02:47:30 +0000</pubDate>
				<category><![CDATA[Arduino Tutorial]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7210</guid>

					<description><![CDATA[<p>&#160; A PID controller is a must-have for any control system aiming for stability. I’ve introduced how to implement PID using an Arduino microcontroller. Now, I’ll be applying PID in the design of a beginner robot project, a line follower. A line follower does what it’s named after. An optical sensor distinguishes a black line &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/implementing-pid-for-a-line-follower-robot/">Implementing PID for a Line Follower Robot</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>&nbsp;</p>
<p>A PID controller is a must-have for any control system aiming for stability. I’ve introduced how to implement <a href="https://www.teachmemicro.com/arduino-pid-control-tutorial/">PID using an Arduino</a> microcontroller. Now, I’ll be applying PID in the design of a beginner robot project, a line follower.</p>
<p>A line follower does what it’s named after. An optical sensor distinguishes a black line from a lighter background. Only two sensors are needed at a minimum but the best line-followers often use more. The information from the sensors is then used by a microcontroller to steer the robot.</p>
<p>The simplest logic for a line follower robot is the following:</p>
<blockquote><p>Is the black line on the right? Then move to the right<br />
Is the black line on the left? Then move to the left<br />
Is there no black line? (Or line in the middle?) Go<br />
All are black (all sensors trigger)? Stop</p></blockquote>
<p>This “bang-bang” logic is enough for a slow-moving robot with simple tracks. But you’ll notice something odd with this algorithm. See the video below:</p>
<p><iframe loading="lazy" width="640" height="480" src="https://drive.google.com/file/d/13k5NsLepOrOjtEijvTEwOr4DzTttdpp2/preview"></iframe></p>
<p>While the robot indeed does follow the line, it bobs left and right as it goes. Here is another example video:</p>
<p><iframe loading="lazy" width="640" height="480" src="https://drive.google.com/file/d/1J1imud21UGLXeKBwvhCsKZYSlwEPOSA1/preview"></iframe></p>
<p>Why does this happen? Consider the illustration below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.teachmemicro.com/wp-content/uploads/2024/07/pid-line-follower-1.jpg" /></p>
<p>As the robot passes a curve, it rotates towards the direction of the line. The rotation or correction is the same throughout. This makes the robot overshoot and thus keeps correcting itself even if it’s out of the curve and in a straight line.</p>
<p>Correcting the robot depending on how far the line is from the center is much better. While this requires more sensors, it is a better design.</p>
<p><img decoding="async" class="aligncenter" src="https://www.teachmemicro.com/wp-content/uploads/2024/07/pid-line-follower-2.jpg" /></p>
<p>Here we have 6 sensors. If the two sensors in the middle trigger, this means the robot goes straight. As the line moves towards the right, the magnitude of correction increases. When the line triggers only the rightmost sensor, the robot has to make the greatest correction.</p>
<p>This algorithm is not bang-bang anymore but is known as <em>proportional control</em>.</p>
<p>But as I’ve mentioned <a href="https://www.teachmemicro.com/arduino-pid-control-tutorial/">in this post</a>, proportional control tends to produce an offset. This is when the controlled variable moves away from its original set point. In the case of our line-follower, our set point is the robot being in the middle of the line. When the robot’s correction overshoots due to a disturbance, it will tend to bob as it did with bang-bang control. See the diagram below:</p>
<p><img decoding="async" class="aligncenter" src="https://www.teachmemicro.com/wp-content/uploads/2024/07/pid-line-follower-3.jpg" /></p>
<p>Since the amount of correction is fixed according to the amount of error (distance from the black line), the robot will find it very hard to move straight in a straight black line again.</p>
<p>Adding Integral and Derivative controllers will drastically improve the performance of the line-follower robot. The integral controller will reduce the offset as it monitors all past error values. As long as the offset is there, the Integral controller will keep producing values to make it zero.</p>
<p>The derivative controller, meanwhile, will look at how fast the error is changing. This effect is particularly evident in different degrees of curves. A sharper curve means the line follower must react faster compared to a flatter curve. The error (distance from the center) changes value as the robot follows the curve. The derivative controller deals with this by adjusting the speed of the turn depending on how fast the error changes.</p>
<h3><strong>PID Control Implementation</strong></h3>
<p>To implement PID control in our line-follower robot, we need to combine the Proportional, Integral, and Derivative components. This combination ensures that the robot adjusts its movement based on current, past, and future errors, leading to smoother and more accurate line following.</p>
<p><strong>Proportional (P) Control</strong> - The Proportional control component adjusts the robot's direction based on the current distance from the center of the line. The greater the distance, the larger the correction. This helps to reduce the immediate error but can still cause oscillations if used alone.</p>
<p><strong>Integral (I) Control</strong> - The Integral control component sums up all past errors and adjusts the robot's direction to eliminate any accumulated offset. This helps to correct any persistent deviation from the line over time, ensuring the robot stays centered.</p>
<p><strong>Derivative (D) Control</strong>  - The Derivative control component predicts future errors by analyzing the rate of change of the current error. This helps to dampen the oscillations caused by the Proportional control, leading to smoother movement.</p>
<h3><strong>Combining PID Components</strong></h3>
<p>By combining these three components, we can fine-tune the robot's response to line deviations. The formula for the PID controller is:</p>
<p><img decoding="async" class="aligncenter" src="https://latex.codecogs.com/gif.latex?Correction%3DK_%7Bp%7D%20%5Ccdot%20Error&amp;plus;K_%7Bi%7D%5Ccdot%20%5Cint%20Error%5C%2C%20dt&amp;plus;K_%7Bd%7D%5Ccdot%20%5Cfrac%7Bd%28Error%29%7D%7Bdt%7D" /></p>
<p>where K<sub>p</sub>​, K<sub>i​</sub>, and K<sub>d</sub>​ are the coefficients for the Proportional, Integral, and Derivative components, respectively.</p>
<h3><strong>Implementing PID Control on Arduino</strong></h3>
<p>Here's a sample code snippet to implement PID control on an Arduino:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">long sensor[] = {0, 1, 2, 3, 4}; //leftmost - 0, rightmost - 4

int rmf = 9;
int rmb = 6;
int lmf = 10; 
int lmb = 11;

//speeds
int rspeed;
int lspeed;
const int base_speed = 255;

int pos;
long sensor_average;
int sensor_sum;

int button = 3; //to be pressed to find set point

float p;
float i;
float d;
float lp;
float error;
float correction;
float sp;

float Kp = 5; 
float Ki = 0; 
float Kd = 40; 

void pid_calc();
void calc_turn();
void motor_drive(int , int );

void setup()
{
  //sensors
  pinMode(A0, INPUT);
  pinMode(A1, INPUT);
  pinMode(A2, INPUT);
  pinMode(A3, INPUT);
  pinMode(A4, INPUT);

  //motors
  pinMode(rmf, OUTPUT);
  pinMode(rmb, OUTPUT);
  pinMode(lmf, OUTPUT);
  pinMode(lmb, OUTPUT);

  Serial.begin(9600);
  
  //finding set point

  while(button)
  {
    sensor_average = 0;
    sensor_sum = 0;
  
    for (int i = -2; i &lt;= 2; i++)
    {
      sensor[i] = analogRead(i);
      sensor_average += sensor[i] * i * 1000;   //weighted mean   
      sensor_sum += int(sensor[i]);
    }
  
    pos = int(sensor_average / sensor_sum);
  
    Serial.print(sensor_average);
    Serial.print(&#039; &#039;);
    Serial.print(sensor_sum);
    Serial.print(&#039; &#039;);
    Serial.print(pos);
    Serial.println();
    delay(2000);
  }

  sp = pos;
}

void loop()
{
  pid_calc();
  calc_turn();
}

void pid_calc()
{
  sensor_average = 0;
  sensor_sum = 0;
  i = 0;

  for(int i = -2; i &lt;= 2; i++)
  {
    sensor[i]=analogRead(i);
    sensor_average = sensor[i]*i*1000; //weighted mean
    sensor_sum += sensor[i];
  }

  pos = int(sensor_average / sensor_sum);

  error = pos-sp;

  p = error;
  i += p;
  d = p - lp;

  lp = p;

  correction = int(Kp*p + Ki*i + Kd*d);
}

void calc_turn()
{
  rspeed = base_speed + correction;
  lspeed = base_speed - correction;

  //restricting speeds of motors between 255 and -255
  
  if (rspeed &gt; 255) 
    rspeed = 255;
    
  if (lspeed &gt; 255) 
    lspeed = 255;
    
  if (rspeed &lt; -255) 
    rspeed = -255;
    
  if (lspeed &lt; -255) 
    lspeed = -255;
 
 motor_drive(rspeed,lspeed);  
}

void motor_drive(int right, int left){
  
  if(right&gt;0)
  {
    analogWrite(rmf, right);   
    analogWrite(rmb, 0);
  }
  else 
  {
    analogWrite(rmf, 0); 
    analogWrite(rmb, abs(right));
  }
  
 
  if(left&gt;0)
  {
    analogWrite(lmf, left);
    analogWrite(lmb, 0);
  }
  else 
  {
    analogWrite(lmf, 0);
    analogWrite(lmb, abs(left));
  }
  
}</code></pre></pre>
</div>
<p>Here, the robot uses an array of sensors (<em>long sensor[] = {0, 1, 2, 3, 4}</em>) to detect the line and motors controlled by specific pins (<em>rmf = 9, rmb = 6, lmf = 10, lmb = 11</em>) to adjust its direction. The setup function initializes the sensors and motors, and a button press determines the set point (sp), representing the desired position of the robot on the line. The PID controller's gains (<em>Kp, Ki, Kd</em>) are defined, with initial dummy values for proportional, integral, and derivative terms, respectively.</p>
<p>In the loop, the <em>pid_calc(</em>) function calculates the error between the current position (<em>pos</em>) and the set point, updating the PID terms and computing the correction. This correction adjusts the motor speeds (<em>rspeed</em> and <em>lspeed</em>), ensuring the robot follows the line accurately. The <em>calc_turn()</em> function determines the appropriate motor speeds based on the correction and limits them within the range of -255 to 255. Finally, <em>motor_drive(int right, int left)</em> applies these speeds to the motors, ensuring the robot's movement aligns with the PID controller's output. The result is a smoother and more accurate line-following behavior compared to simpler control methods.</p>
<h3><strong>Tuning PID Coefficients</strong></h3>
<p>Tuning the K<sub>p</sub>​, K<sub>i​</sub>, and K<sub>d</sub> coefficients is crucial for optimal performance. This process often involves trial and error:</p>
<ul>
<li>Start with K<sub>p</sub>: Increase K<sub>p</sub>​ until the robot starts oscillating around the line.</li>
<li>Adjust K<sub>i​</sub>​: Increase K<sub>i​</sub> to eliminate any steady-state error.</li>
<li>Fine-tune with K<sub>d</sub>​: Increase K<sub>d</sub>​ to dampen the oscillations.</li>
</ul>
<h3><strong>Conclusion</strong></h3>
<p>Using a PID controller significantly improves the performance of a line-follower robot compared to simple bang-bang control. By considering the current error, accumulated past errors, and the rate of error change, the robot can follow the line more accurately and smoothly. This project not only demonstrates the effectiveness of PID control but also provides a solid foundation for more advanced robotics projects.</p>
<p>Happy building and coding!</p>
<p>The post <a href="https://www.teachmemicro.com/implementing-pid-for-a-line-follower-robot/">Implementing PID for a Line Follower Robot</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 

Served from: www.teachmemicro.com @ 2026-06-20 18:32:26 by W3 Total Cache
-->