<?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>Reference Archives | Microcontroller Tutorials</title>
	<atom:link href="https://www.teachmemicro.com/category/reference/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.teachmemicro.com/category/reference/</link>
	<description>Microcontroller Tutorials and Resources</description>
	<lastBuildDate>Tue, 21 Jul 2026 03:15:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://www.teachmemicro.com/wp-content/uploads/2019/04/blue-icon-65x65.png</url>
	<title>Reference Archives | Microcontroller Tutorials</title>
	<link>https://www.teachmemicro.com/category/reference/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Ring Buffer Visualizer for Embedded Systems</title>
		<link>https://www.teachmemicro.com/ring-buffer-visualizer-for-embedded-systems/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ring-buffer-visualizer-for-embedded-systems</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Tue, 21 Jul 2026 03:15:47 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=12313</guid>

					<description><![CDATA[<p>A ring buffer in embedded systems is a fixed-size memory area used to temporarily store data. You will often find one between a fast peripheral and a slower part of the program. A UART interrupt, for example, can place received bytes into a ring buffer while the main application processes those bytes whenever it has &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/ring-buffer-visualizer-for-embedded-systems/">Ring Buffer Visualizer for Embedded Systems</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>A <strong>ring buffer in embedded systems</strong> is a fixed-size memory area used to temporarily store data. You will often find one between a fast peripheral and a slower part of the program. A UART interrupt, for example, can place received bytes into a ring buffer while the main application processes those bytes whenever it has time.</p>
<p>A ring buffer is also called a <strong>circular buffer</strong>. The memory itself is still an ordinary C array. What makes it circular is the way its indexes return to zero after reaching the final array element.</p>
<p>This tutorial explains how an embedded ring buffer works, how its <em>head</em> and <em>tail</em> pointers move, and how you can implement one in C. You can also use the interactive visualizer below to see each operation happen.</p>
<p><span id="more-12313"></span></p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Interactive Embedded Ring Buffer Visualizer</strong></h2>
<p>Enter a character, decimal byte, or hexadecimal value and click <strong>Write Byte</strong>. The value is stored at the current head position. Click <strong>Read Byte</strong> to remove the oldest value from the tail position.</p>
<p>Watch what happens when either pointer reaches the final slot. Instead of moving outside the array, it wraps around to index zero.</p>
        <div
            id="tmm-rbv-1"
            class="tmm-rbv-app"
            data-rbv-instance="tmm-rbv-1"
            data-rbv-buffer-size="8"
        >
            <section class="tmm-rbv-card" aria-labelledby="tmm-rbv-1-buffer-title">
                <noscript>
                    <div class="tmm-rbv-noscript">
                        JavaScript is required for the interactive ring buffer visualizer.                    </div>
                </noscript>

                <div class="tmm-rbv-topline">
                    <h3 id="tmm-rbv-1-buffer-title">
                        Ring Buffer                    </h3>
                    <p>
                        Count-based FIFO storage for embedded UART bytes.                    </p>
                </div>

                <div class="tmm-rbv-buffer-area">
                    <div
                        class="tmm-rbv-buffer"
                        data-rbv-el="buffer"
                        role="img"
                        aria-label="Circular ring buffer slots with head and tail indicators"
                    ></div>
                    <div class="tmm-rbv-legend" aria-label="Pointer legend">
                        <span><strong class="tmm-rbv-head-text">HEAD</strong>: next write position</span>
                        <span><strong class="tmm-rbv-tail-text">TAIL</strong>: next read position</span>
                    </div>
                </div>

                <div class="tmm-rbv-controls">
                    <label class="tmm-rbv-value-field" for="tmm-rbv-1-value">
                        <span>Byte or character</span>
                        <input
                            id="tmm-rbv-1-value"
                            data-rbv-el="value-input"
                            type="text"
                            inputmode="text"
                            autocomplete="off"
                            maxlength="6"
                            placeholder="A or 0x41"
                        >
                    </label>
                    <button class="tmm-rbv-button" type="button" data-rbv-action="write">
                        Write Byte                    </button>
                    <button class="tmm-rbv-button tmm-rbv-button--secondary" type="button" data-rbv-action="read">
                        Read Byte                    </button>
                    <button class="tmm-rbv-button tmm-rbv-button--muted" type="button" data-rbv-action="reset">
                        Reset                    </button>
                </div>

                <div class="tmm-rbv-uart-row">
                    <label class="tmm-rbv-toggle" for="tmm-rbv-1-uart-toggle">
                        <input id="tmm-rbv-1-uart-toggle" data-rbv-el="uart-toggle" type="checkbox">
                        <span>Simulate UART RX</span>
                    </label>
                    <button class="tmm-rbv-button tmm-rbv-button--secondary" type="button" data-rbv-action="uart-start" disabled>
                        Start UART                    </button>
                    <button class="tmm-rbv-button tmm-rbv-button--muted" type="button" data-rbv-action="uart-stop" disabled>
                        Stop UART                    </button>
                    <span class="tmm-rbv-uart-label" data-rbv-el="uart-label">
                        UART RX idle.                    </span>
                </div>

                <div class="tmm-rbv-status" id="tmm-rbv-1-status" data-rbv-el="status">
                    <span>Head: <strong data-rbv-el="head">0</strong></span>
                    <span>Tail: <strong data-rbv-el="tail">0</strong></span>
                    <span>Used: <strong data-rbv-el="used">0 / 8</strong></span>
                    <span>State: <strong data-rbv-el="state">EMPTY</strong></span>
                </div>

                <p
                    class="tmm-rbv-message"
                    id="tmm-rbv-1-message"
                    data-rbv-el="message"
                    aria-live="polite"
                >
                    Buffer is empty. Write a byte to begin.                </p>

                <details class="tmm-rbv-code" aria-labelledby="tmm-rbv-1-code-title">
                    <summary id="tmm-rbv-1-code-title">
                        Equivalent Embedded C                    </summary>
                    <button class="tmm-rbv-button tmm-rbv-button--copy" type="button" data-rbv-action="copy-code">
                        Copy Code                    </button>
                    <pre><code data-rbv-el="code">#define BUFFER_SIZE 8

typedef struct
{
    uint8_t data[BUFFER_SIZE];
    volatile uint8_t head;
    volatile uint8_t tail;
    volatile uint8_t count;
} RingBuffer;

bool ring_buffer_write(RingBuffer *rb, uint8_t value)
{
    if (rb-&gt;count &gt;= BUFFER_SIZE)
    {
        return false;
    }

    rb-&gt;data[rb-&gt;head] = value;
    rb-&gt;head = (rb-&gt;head + 1U) % BUFFER_SIZE;
    rb-&gt;count++;

    return true;
}

bool ring_buffer_read(RingBuffer *rb, uint8_t *value)
{
    if (rb-&gt;count == 0U)
    {
        return false;
    }

    *value = rb-&gt;data[rb-&gt;tail];
    rb-&gt;tail = (rb-&gt;tail + 1U) % BUFFER_SIZE;
    rb-&gt;count--;

    return true;
}</code></pre>
                </details>
            </section>
        </div>
        
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>What Is a Ring Buffer in Embedded Systems?</strong></h2>
<p>A ring buffer is a <strong>first-in, first-out</strong> or FIFO data structure built using a fixed-size array. The first value written into the buffer is normally the first value read from it.</p>
<p>Consider this eight-byte array:</p>
<pre><pre><code class="language-cpp">uint8_t buffer[8];</code></pre></pre>
<p>A normal queue implementation might remove the first value and then shift every remaining value toward index zero. That approach works, but repeatedly moving data wastes processor time.</p>
<p>A ring buffer does not shift its contents. Instead, it keeps track of two indexes:</p>
<ul>
<li><strong>Head</strong> — the position where the next value will be written</li>
<li><strong>Tail</strong> — the position where the next value will be read</li>
</ul>
<p>When a value is written, the head advances. When a value is read, the tail advances. The data remains in the same physical array slots until those slots are reused.</p>
<p>This makes ring-buffer writes and reads fast and predictable. Both operations normally take constant time because no existing elements have to be moved.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Why Ring Buffers Are Useful in Embedded Applications</strong></h2>
<p>Microcontrollers often deal with events that do not happen at exactly the same speed as the main application.</p>
<p>For example, a UART peripheral may receive a byte while the processor is:</p>
<ul>
<li>Updating a display</li>
<li>Reading a sensor</li>
<li>Writing data to flash memory</li>
<li>Processing a communication packet</li>
<li>Executing another part of the main loop</li>
</ul>
<p>The UART receive interrupt should not perform a large amount of processing. It should normally retrieve the received byte quickly, store it somewhere safe, and then return.</p>
<p>A ring buffer provides that temporary storage:</p>
<pre><pre><code class="language-cpp">UART peripheral → RX interrupt → Ring buffer → Main application</code></pre></pre>
<p>The interrupt acts as the <strong>producer</strong> because it adds bytes. The main application acts as the <strong>consumer</strong> because it removes and processes them.</p>
<p>The same idea can be used for:</p>
<ul>
<li>UART receive and transmit queues</li>
<li>ADC sample storage</li>
<li>Sensor-data collection</li>
<li>Logging systems</li>
<li>CAN and SPI message queues</li>
<li>Audio samples</li>
<li>Keyboard or keypad input</li>
<li>Data moving between interrupt handlers and the main loop</li>
</ul>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>How the Head Pointer Works</strong></h2>
<p>The head points to the array position where the next byte will be stored.</p>
<p>Suppose the head is initially at index zero:</p>
<pre><pre><code class="language-cpp">head = 0;</code></pre></pre>
<p>Writing the character <em>'A'</em> stores it in <em>buffer[0]</em>. The head then moves to index one.</p>
<pre><pre><code class="language-cpp">buffer[head] = &#039;A&#039;;
head++;</code></pre></pre>
<p>If the next value is <em>'B'</em>, it is stored in <em>buffer[1]</em>, after which the head moves to index two.</p>
<p>The head always identifies the <em>next available write position</em>. It does not normally point to the most recently written value.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>How the Tail Pointer Works</strong></h2>
<p>The tail points to the oldest unread value.</p>
<p>If the tail is at index zero, reading from the buffer returns the value stored in <em>buffer[0]</em>. The tail then advances to index one.</p>
<pre><pre><code class="language-cpp">value = buffer[tail];
tail++;</code></pre></pre>
<p>The contents do not need to be shifted after the read. The application simply considers that slot available again.</p>
<p>Some implementations clear a slot after reading it because doing so makes debugging and visualization easier. Clearing the slot is not normally required for the ring-buffer algorithm itself.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Pointer Wraparound</strong></h2>
<p>The circular behavior appears when a pointer reaches the end of the array.</p>
<p>For an eight-element buffer, the valid indexes are zero through seven. If the head is at index seven, its next position must be index zero.</p>
<p>This can be written using the modulo operator:</p>
<pre><pre><code class="language-cpp">head = (head + 1U) % BUFFER_SIZE;</code></pre></pre>
<p>With <em>BUFFER_SIZE</em> equal to eight:</p>
<pre><pre><code class="language-cpp">(7 + 1) % 8 = 0</code></pre></pre>
<p>The same operation is used for the tail:</p>
<pre><pre><code class="language-cpp">tail = (tail + 1U) % BUFFER_SIZE;</code></pre></pre>
<p>No data is physically moved from the end of the array back to the beginning. Only the index wraps around.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Detecting an Empty or Full Ring Buffer</strong></h2>
<p>A ring buffer must be able to determine whether another read or write is allowed.</p>
<p>The interactive visualizer uses a <strong>count-based implementation</strong>. In addition to the head and tail, it stores the number of elements currently inside the buffer.</p>
<pre><pre><code class="language-cpp">uint8_t head;
uint8_t tail;
uint8_t count;</code></pre></pre>
<p>The buffer is empty when:</p>
<pre><pre><code class="language-cpp">count == 0</code></pre></pre>
<p>It is full when:</p>
<pre><pre><code class="language-cpp">count == BUFFER_SIZE</code></pre></pre>
<p>This method allows every array element to be used. An eight-element array can hold eight values.</p>
<p>Another common method avoids the count variable and reserves one array slot. In that version:</p>
<ul>
<li><em>head == tail</em> means the buffer is empty.</li>
<li>The buffer is full when advancing the head would make it equal to the tail.</li>
</ul>
<p>That approach is especially useful for a single-producer, single-consumer ring buffer because the producer can own the head while the consumer owns the tail. I will return to that version later in the tutorial.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Basic Count-Based Ring Buffer in C</strong></h2>
<p>The following implementation matches the behavior of the visualizer. It stores eight bytes and rejects new data when the buffer is full.</p>
<pre><pre><code class="language-cpp">#include &lt;stdbool.h&gt;
#include &lt;stdint.h&gt;

#define BUFFER_SIZE 8U

typedef struct
{
    uint8_t data[BUFFER_SIZE];
    uint8_t head;
    uint8_t tail;
    uint8_t count;
} RingBuffer;</code></pre></pre>
<h3><strong>Initializing the Buffer</strong></h3>
<p>Initialization places both pointers at index zero and sets the stored count to zero.</p>
<pre><pre><code class="language-cpp">void ring_buffer_init(RingBuffer *rb)
{
    rb-&gt;head = 0U;
    rb-&gt;tail = 0U;
    rb-&gt;count = 0U;
}</code></pre></pre>
<p>The actual data array does not have to be cleared because no slot is considered valid while the count is zero.</p>
<h3><strong>Writing a Byte</strong></h3>
<pre><pre><code class="language-cpp">bool ring_buffer_write(RingBuffer *rb, uint8_t value)
{
    if (rb-&gt;count &gt;= BUFFER_SIZE)
    {
        return false;
    }

    rb-&gt;data[rb-&gt;head] = value;
    rb-&gt;head = (rb-&gt;head + 1U) % BUFFER_SIZE;
    rb-&gt;count++;

    return true;
}</code></pre></pre>
<p>The function first checks whether the buffer is full. If space is available, the value is written at the head position. The head advances, and the element count increases.</p>
<p>The function returns <em>false</em> when no more data can be accepted. The caller can use this result to record an overflow, increment an error counter, or take another appropriate action.</p>
<h3><strong>Reading a Byte</strong></h3>
<pre><pre><code class="language-cpp">bool ring_buffer_read(RingBuffer *rb, uint8_t *value)
{
    if (rb-&gt;count == 0U)
    {
        return false;
    }

    *value = rb-&gt;data[rb-&gt;tail];
    rb-&gt;tail = (rb-&gt;tail + 1U) % BUFFER_SIZE;
    rb-&gt;count--;

    return true;
}</code></pre></pre>
<p>The read function checks for an empty buffer before accessing the array. It returns the oldest byte, advances the tail, and decreases the count.</p>
<h3><strong>Checking the Current State</strong></h3>
<pre><pre><code class="language-cpp">bool ring_buffer_is_empty(const RingBuffer *rb)
{
    return rb-&gt;count == 0U;
}

bool ring_buffer_is_full(const RingBuffer *rb)
{
    return rb-&gt;count == BUFFER_SIZE;
}

uint8_t ring_buffer_used(const RingBuffer *rb)
{
    return rb-&gt;count;
}

uint8_t ring_buffer_free(const RingBuffer *rb)
{
    return BUFFER_SIZE - rb-&gt;count;
}</code></pre></pre>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>A Simple Ring Buffer Example</strong></h2>
<p>Here is how the buffer can be used from a normal C program:</p>
<pre><pre><code class="language-cpp">RingBuffer rx_buffer;
uint8_t received_byte;

int main(void)
{
    ring_buffer_init(&amp;rx_buffer);

    ring_buffer_write(&amp;rx_buffer, &#039;A&#039;);
    ring_buffer_write(&amp;rx_buffer, &#039;B&#039;);
    ring_buffer_write(&amp;rx_buffer, &#039;C&#039;);

    if (ring_buffer_read(&amp;rx_buffer, &amp;received_byte))
    {
        /* received_byte contains &#039;A&#039; */
    }

    if (ring_buffer_read(&amp;rx_buffer, &amp;received_byte))
    {
        /* received_byte contains &#039;B&#039; */
    }

    while (1)
    {
        /* Main application */
    }
}</code></pre></pre>
<p>Even if the head wraps around while more values are written, the tail continues to return them in FIFO order.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Using a Ring Buffer for UART Reception</strong></h2>
<p>A UART receive ring buffer is one of the most common embedded applications.</p>
<p>The general flow is:</p>
<ol>
<li>The UART peripheral receives a byte.</li>
<li>The receive interrupt runs.</li>
<li>The interrupt reads the UART data register.</li>
<li>The byte is written into the ring buffer.</li>
<li>The interrupt returns.</li>
<li>The main loop later reads and processes the buffered byte.</li>
</ol>
<p>A simplified interrupt handler might look like this:</p>
<pre><pre><code class="language-cpp">void UART_RX_IRQHandler(void)
{
    uint8_t value = uart_read_data_register();

    if (!ring_buffer_write(&amp;rx_buffer, value))
    {
        uart_rx_overflow = true;
    }
}</code></pre></pre>
<p>The main loop can process the data without waiting inside the interrupt:</p>
<pre><pre><code class="language-cpp">int main(void)
{
    uint8_t value;

    ring_buffer_init(&amp;rx_buffer);
    uart_init();

    while (1)
    {
        while (ring_buffer_read(&amp;rx_buffer, &amp;value))
        {
            process_received_byte(value);
        }

        run_other_application_tasks();
    }
}</code></pre></pre>
<p>This arrangement lets the interrupt capture incoming data quickly while the main application performs the more time-consuming work.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>A Concurrency Warning About the Count Variable</strong></h2>
<p>The count-based implementation is easy to understand and works well for the visualizer. However, notice what happens in the UART example:</p>
<ul>
<li>The interrupt increases <em>count</em>.</li>
<li>The main loop decreases <em>count</em>.</li>
</ul>
<p>Both execution contexts modify the same variable. An interrupt occurring during a read-modify-write operation may produce a race condition, depending on the microcontroller, variable width, compiler, and generated instructions.</p>
<p>Adding <em>volatile</em> prevents the compiler from treating a shared variable as if it never changes unexpectedly. It does <strong>not</strong> automatically make an operation atomic, and it does not by itself solve every concurrency problem.</p>
<p>You can protect a count-based implementation with a short critical section. Another option is to use a single-producer, single-consumer design where the interrupt modifies only the head and the main loop modifies only the tail.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Single-Producer, Single-Consumer UART Ring Buffer</strong></h2>
<p>For a typical UART receive buffer, there is one producer and one consumer:</p>
<ul>
<li>The UART RX interrupt is the only code that changes the head.</li>
<li>The main loop is the only code that changes the tail.</li>
</ul>
<p>The implementation below reserves one array slot so that <em>head == tail</em> can unambiguously represent an empty buffer.</p>
<pre><pre><code class="language-cpp">#include &lt;stdbool.h&gt;
#include &lt;stdint.h&gt;

#define UART_BUFFER_SIZE 16U
#define UART_BUFFER_MASK (UART_BUFFER_SIZE - 1U)

typedef struct
{
    uint8_t data[UART_BUFFER_SIZE];
    volatile uint16_t head;
    volatile uint16_t tail;
} UartRingBuffer;</code></pre></pre>
<p>Because the masking optimization is used here, <em>UART_BUFFER_SIZE</em> must be a power of two.</p>
<h3><strong>Writing from the UART Interrupt</strong></h3>
<pre><pre><code class="language-cpp">bool uart_ring_buffer_write_isr(
    UartRingBuffer *rb,
    uint8_t value)
{
    uint16_t head = rb-&gt;head;
    uint16_t next =
        (head + 1U) &amp; UART_BUFFER_MASK;

    if (next == rb-&gt;tail)
    {
        return false;
    }

    rb-&gt;data[head] = value;
    rb-&gt;head = next;

    return true;
}</code></pre></pre>
<h3><strong>Reading from the Main Loop</strong></h3>
<pre><pre><code class="language-cpp">bool uart_ring_buffer_read(
    UartRingBuffer *rb,
    uint8_t *value)
{
    uint16_t tail = rb-&gt;tail;

    if (tail == rb-&gt;head)
    {
        return false;
    }

    *value = rb-&gt;data[tail];
    rb-&gt;tail =
        (tail + 1U) &amp; UART_BUFFER_MASK;

    return true;
}</code></pre></pre>
<p>This arrangement avoids a shared count variable. The producer publishes a new head only after writing the byte, while the consumer advances the tail only after retrieving it.</p>
<p>You should still check the requirements of your specific architecture. Index reads and writes should be naturally aligned and atomic for the chosen index type. Systems with multiple cores, DMA, an RTOS, cache coherency concerns, or more than one producer or consumer may require memory barriers, critical sections, or an operating-system synchronization primitive.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Modulo Versus Bit Masking</strong></h2>
<p>The general wraparound operation uses modulo:</p>
<pre><pre><code class="language-cpp">next = (index + 1U) % BUFFER_SIZE;</code></pre></pre>
<p>This works for any valid buffer size.</p>
<p>If the size is a power of two, the index can instead be wrapped using a mask:</p>
<pre><pre><code class="language-cpp">next = (index + 1U) &amp; (BUFFER_SIZE - 1U);</code></pre></pre>
<p>For example, valid indexes for a 16-byte buffer are zero through 15. The value <em>BUFFER_SIZE - 1</em> is therefore <em>0x0F</em>.</p>
<p>Modern compilers can often optimize a constant modulo operation automatically. I would therefore prioritize clear and correct code first, then inspect the generated code if performance is critical.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Ring Buffer Overflow and Underflow</strong></h2>
<h3><strong>Overflow</strong></h3>
<p>An overflow occurs when the producer attempts to write while no space is available.</p>
<p>The buffer can respond in different ways:</p>
<ul>
<li>Reject the new value</li>
<li>Overwrite the oldest unread value</li>
<li>Set an overflow flag</li>
<li>Increment a lost-byte counter</li>
<li>Apply flow control when the protocol supports it</li>
</ul>
<p>The visualizer rejects the new byte because this makes the loss of data obvious. Whether that is the correct behavior in a real project depends on the application.</p>
<p>For a command interface, losing an old or new character may invalidate the entire command. For continuous sensor history, overwriting the oldest sample may be acceptable.</p>
<h3><strong>Underflow</strong></h3>
<p>An underflow occurs when the consumer attempts to read an empty buffer.</p>
<p>A well-designed read function should detect this before accessing the array. Returning a Boolean result is useful because every possible byte value, including zero, may be valid data.</p>
<pre><pre><code class="language-cpp">uint8_t value;

if (ring_buffer_read(&amp;rx_buffer, &amp;value))
{
    process_received_byte(value);
}
else
{
    /* No data currently available */
}</code></pre></pre>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Choosing the Ring Buffer Size</strong></h2>
<p>The correct buffer size depends on how quickly data arrives and how long the consumer may be unable to process it.</p>
<p>A useful starting estimate is:</p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_36c3ba47aec8bea6fe7cfe96cf26d71b.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="N_{\min} \ge R_{\text{bytes}}T_{\text{delay}} + M" /></span><script type='math/tex'>N_{\min} \ge R_{\text{bytes}}T_{\text{delay}} + M</script></p>
<p>Where:</p>
<ul>
<li><strong>N<sub>min</sub></strong> is the minimum number of required slots.</li>
<li><strong>R<sub>bytes</sub></strong> is the incoming data rate in bytes per second.</li>
<li><strong>T<sub>delay</sub></strong> is the longest expected consumer delay in seconds.</li>
<li><strong>M</strong> is an additional safety margin.</li>
</ul>
<p>For example, an 8-N-1 UART connection at 115200 baud uses approximately ten transmitted bits for every data byte: one start bit, eight data bits, and one stop bit.</p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_13803e89537e1b130570a49228941c86.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="R_{\text{bytes}} \approx \frac{115200}{10} = 11520\text{ bytes/s}" /></span><script type='math/tex'>R_{\text{bytes}} \approx \frac{115200}{10} = 11520\text{ bytes/s}</script></p>
<p>If the main application can be delayed for 5 milliseconds:</p>
<p><span class='MathJax_Preview'><img src='https://www.teachmemicro.com/wp-content/plugins/latex/cache/tex_79901569c7af45e0cd758adc090dd800.gif' style='vertical-align: middle; border: none; padding-bottom:2px;' class='tex' alt="N_{\min} \ge 11520 \times 0.005 = 57.6\text{ bytes}" /></span><script type='math/tex'>N_{\min} \ge 11520 \times 0.005 = 57.6\text{ bytes}</script></p>
<p>A 64-byte buffer is the smallest convenient power-of-two choice, but it leaves almost no margin. A 128-byte buffer may be more appropriate if RAM permits and occasional longer delays are possible.</p>
<p>If the implementation reserves one slot, remember that a 64-element array stores only 63 bytes.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Ring Buffer Versus an Ordinary Linear Buffer</strong></h2>
<div style="overflow-x: auto;">
<table>
<thead>
<tr>
<th>Feature</th>
<th>Ring Buffer</th>
<th>Linear Buffer with Shifting</th>
</tr>
</thead>
<tbody>
<tr>
<td>Memory allocation</td>
<td>Fixed</td>
<td>Usually fixed</td>
</tr>
<tr>
<td>Write operation</td>
<td>Advances head</td>
<td>Adds at the end</td>
</tr>
<tr>
<td>Read operation</td>
<td>Advances tail</td>
<td>May shift remaining values</td>
</tr>
<tr>
<td>Wraparound</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Read and write time</td>
<td>Normally constant</td>
<td>May increase when shifting</td>
</tr>
<tr>
<td>Common embedded use</td>
<td>UART, ADC, logging and streaming</td>
<td>Small packets and simple temporary storage</td>
</tr>
</tbody>
</table>
</div>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Common Ring Buffer Mistakes</strong></h2>
<h3><strong>Confusing the Head with the Last Written Position</strong></h3>
<p>In the implementation used here, the head is the <em>next</em> write position. After writing to index three, the head normally advances to index four.</p>
<h3><strong>Failing to Distinguish Full from Empty</strong></h3>
<p>If the head and tail can be equal in both states, another piece of information is required. Use a count, reserve one slot, or store a separate full flag.</p>
<h3><strong>Using an Index That Is Too Small</strong></h3>
<p>The index type must be able to represent every valid buffer position. An eight-bit index is sufficient for buffers up to 256 elements, but larger buffers require a wider type.</p>
<h3><strong>Assuming Volatile Makes Everything Thread-Safe</strong></h3>
<p><em>volatile</em> affects compiler optimization. It does not automatically protect a multi-step update from interrupts, multiple tasks, or another processor core.</p>
<h3><strong>Doing Too Much Work Inside the Interrupt</strong></h3>
<p>The receive interrupt should normally store the byte and return. Packet parsing, command execution, display updates, and other longer operations are better handled outside the ISR.</p>
<h3><strong>Ignoring Overflow</strong></h3>
<p>Even a correctly implemented ring buffer can overflow. Always decide how the application should detect and respond to lost data.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Frequently Asked Questions</strong></h2>
<h3><strong>Is a ring buffer the same as a circular queue?</strong></h3>
<p>The terms are often used interchangeably. Both normally describe FIFO storage that reuses a fixed array by wrapping its indexes. Ring buffer is particularly common terminology in embedded systems, drivers, communications, and streaming applications.</p>
<h3><strong>Does a ring buffer dynamically allocate memory?</strong></h3>
<p>It does not have to. Embedded implementations usually use a statically allocated array so memory usage is known at compile time and no heap allocation is required.</p>
<h3><strong>Can a ring buffer store structures instead of bytes?</strong></h3>
<p>Yes. The array can contain sensor samples, CAN frames, event structures, pointers, or other fixed-size objects.</p>
<pre><pre><code class="language-cpp">typedef struct
{
    uint32_t timestamp;
    int16_t temperature;
    uint16_t pressure;
} SensorSample;

SensorSample sample_buffer[16];</code></pre></pre>
<h3><strong>Should a full ring buffer reject or overwrite data?</strong></h3>
<p>It depends on the application. Communication buffers often reject new data and report an overflow. History buffers may intentionally overwrite the oldest entry so they always contain the most recent samples.</p>
<h3><strong>Can DMA use a ring buffer?</strong></h3>
<p>Yes, although the design becomes more hardware-specific. Many microcontrollers support circular DMA modes that repeatedly fill a memory region. The application must then track which portion of the region has been written and which portion has already been processed.</p>
<h3><strong>Can I use this implementation with an RTOS?</strong></h3>
<p>You can, but a ring buffer shared by multiple tasks may require a mutex, critical section, semaphore, or RTOS queue. A lock-free single-producer, single-consumer implementation should not automatically be treated as safe for multiple producers or consumers.</p>
<div class="clear"></div><div style="margin-top:20px; margin-bottom:20px;" class="divider divider-solid"></div>
<h2><strong>Conclusion</strong></h2>
<p>A ring buffer gives embedded applications an efficient way to temporarily store streaming data without shifting array elements or allocating more memory at runtime.</p>
<p>The basic idea is simple:</p>
<ul>
<li>The head identifies the next write position.</li>
<li>The tail identifies the next read position.</li>
<li>Both pointers return to zero after reaching the end.</li>
<li>Writes must detect a full buffer.</li>
<li>Reads must detect an empty buffer.</li>
</ul>
<p>The count-based approach used by the visualizer is useful for learning because the full and empty conditions are easy to see. For a real UART interrupt and main-loop arrangement, a single-producer, single-consumer implementation with separate head and tail ownership can reduce shared-state problems.</p>
<p>Try filling the visualizer, reading a few bytes, and then writing more values. The most important moment is when the head crosses the final index and returns to zero while the unread values remain in the correct FIFO order. Once that behavior is clear, the C implementation becomes much easier to understand.</p>
<p>The post <a href="https://www.teachmemicro.com/ring-buffer-visualizer-for-embedded-systems/">Ring Buffer Visualizer for Embedded Systems</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32 Pinout Diagram &#124; ESP32-CAM</title>
		<link>https://www.teachmemicro.com/esp32-pinout-diagram-esp32-cam/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32-pinout-diagram-esp32-cam</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 10 Nov 2025 01:00:42 +0000</pubDate>
				<category><![CDATA[Reference]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=9670</guid>

					<description><![CDATA[<p>The ESP32-CAM is a compact yet powerful development board that packs Wi-Fi, Bluetooth, and camera capabilities into one low-cost module. But with its limited pin count and dual-purpose GPIOs, figuring out which pins to use can be confusing—especially for beginners. In this post, we’ll break down the ESP32-CAM pinout, explain the function of each pin, &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp32-pinout-diagram-esp32-cam/">ESP32 Pinout Diagram | ESP32-CAM</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The <strong>ESP32-CAM</strong> is a compact yet powerful development board that packs Wi-Fi, Bluetooth, and camera capabilities into one low-cost module. But with its limited pin count and dual-purpose GPIOs, figuring out which pins to use can be confusing—especially for beginners. In this post, we’ll break down the <strong>ESP32-CAM pinout</strong>, explain the function of each pin, and help you avoid common pitfalls when connecting sensors, peripherals, or programming the board.</p>
<p><span id="more-9670"></span></p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram.avif"><em>(Click to view larger image)</em></a></p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram.avif"><img data-dominant-color="dcdad7" data-has-transparency="false" style="--dominant-color: #dcdad7;" decoding="async" class="aligncenter size-large wp-image-9671 not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram-1024x567.avif" alt="" width="618" height="342" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram-1024x567.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram-300x166.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram-768x425.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram-1536x851.avif 1536w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM-pinout-diagram.avif 1768w" sizes="(max-width: 618px) 100vw, 618px" /></a></p>
<p>&nbsp;</p>
<h3><strong>ESP32-CAM Pinout Description</strong></h3>
<table>
<caption><em>ESP32-CAM (AI-Thinker) — Pinout (name / description)</em></caption>
<thead>
<tr>
<th>Pin Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>5V (VCC)</td>
<td>Primary power input (recommended). Often used to power the board from USB/5V supplies.</td>
</tr>
<tr>
<td>3V3 (3.3V)</td>
<td>3.3V output from the regulator. Can power small external sensors (use with caution).</td>
</tr>
<tr>
<td>GND</td>
<td>Ground (three GND pins available on the board).</td>
</tr>
<tr>
<td>IO0 (GPIO0)</td>
<td>Boot mode select (pull LOW to enter flash mode). Also used as camera XCLK in some setups — don’t leave it strapped incorrectly.</td>
</tr>
<tr>
<td>U0T / IO1 (GPIO1)</td>
<td>UART0 TX (serial transmit). Used by the on-board serial console — avoid reassigning during programming.</td>
</tr>
<tr>
<td>U0R / IO3 (GPIO3)</td>
<td>UART0 RX (serial receive). Used by serial console and required for uploading via UART adapter.</td>
</tr>
<tr>
<td>IO2 (GPIO2)</td>
<td>Used as SD card DATA0 (also available as general I/O if SD not used). Boot-sensitive on some modules.</td>
</tr>
<tr>
<td>IO4 (GPIO4)</td>
<td>SD card DATA1 / often tied to the on-board LED — usable if SD/card not in use.</td>
</tr>
<tr>
<td>IO12 (GPIO12)</td>
<td>SD card DATA2 (also MTDI). Watch this pin’s strapping behavior — avoid if unsure.</td>
</tr>
<tr>
<td>IO13 (GPIO13)</td>
<td>SD card DATA3 (also MTCK). Commonly used by the microSD interface.</td>
</tr>
<tr>
<td>IO14 (GPIO14)</td>
<td>SD card CLK (clock line). Usually occupied when using the microSD slot.</td>
</tr>
<tr>
<td>IO15 (GPIO15)</td>
<td>SD card CMD (command line). Typically used by the onboard microSD card interface.</td>
</tr>
<tr>
<td>IO16 (GPIO16)</td>
<td>General-purpose I/O (limited availability on some board variants).</td>
</tr>
<tr>
<td>IO17 (GPIO17)</td>
<td>General-purpose I/O (limited availability on some board variants).</td>
</tr>
<tr>
<td>GPIO32 (CAM_PWR / PWDN)</td>
<td>Camera power / PWDN control on some board variants (used to enable/disable camera power).</td>
</tr>
<tr>
<td>microSD slot</td>
<td>Uses many of the above pins (IO2, IO4, IO12–IO15, IO14) — if SD is used those pins aren’t free for other peripherals.</td>
</tr>
</tbody>
</table>
<h3><strong>ESP32-CAM Schematic Diagram</strong></h3>
<p>The schematic diagram below is a useful reference, together with the pinout, as you make your project.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH.avif"><em>(Click to view larger image)</em></a></p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH.avif"><img data-dominant-color="f6f3eb" data-has-transparency="true" style="--dominant-color: #f6f3eb;" loading="lazy" decoding="async" class="aligncenter wp-image-9672 size-large has-transparency" src="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH-1024x723.avif" alt="ESP32 CAM Schematic Diagram" width="618" height="436" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH-1024x723.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH-300x212.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH-768x543.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH-1536x1085.avif 1536w, https://www.teachmemicro.com/wp-content/uploads/2025/10/ESP32-CAM_SCH.avif 2000w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a></p>
<p>The post <a href="https://www.teachmemicro.com/esp32-pinout-diagram-esp32-cam/">ESP32 Pinout Diagram | ESP32-CAM</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32 Pinout Diagram &#124; ESP32-WROVER</title>
		<link>https://www.teachmemicro.com/esp32-pinout-diagram-esp32-wrover/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp32-pinout-diagram-esp32-wrover</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 29 Sep 2025 03:18:57 +0000</pubDate>
				<category><![CDATA[Reference]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=9367</guid>

					<description><![CDATA[<p>The ESP32 has become one of the most popular microcontrollers in the maker and IoT community thanks to its power, versatility, and built-in Wi-Fi and Bluetooth features. Among its many modules, the ESP32-WROVER stands out because of its extended memory and performance, making it ideal for demanding projects like data logging, machine learning, or advanced &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp32-pinout-diagram-esp32-wrover/">ESP32 Pinout Diagram | ESP32-WROVER</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The ESP32 has become one of the most popular microcontrollers in the maker and IoT community thanks to its power, versatility, and built-in Wi-Fi and Bluetooth features. Among its many modules, the ESP32-WROVER stands out because of its extended memory and performance, making it ideal for demanding projects like data logging, machine learning, or advanced wireless applications. To make the most of this board, understanding its pinout is essential. Each pin serves a specific purpose—ranging from general-purpose input/output (GPIO) to power, ground, analog, and communication interfaces like SPI, I2C, and UART. In this article, we’ll walk through the ESP32-WROVER pinout diagram in detail so you can confidently connect sensors, modules, and peripherals while avoiding common wiring mistakes.</p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram.avif"><em>(Click to view larger image)</em></a></p>
<p><a href="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram.avif" target="_blank" rel="noopener"><img data-dominant-color="dad8d7" data-has-transparency="false" style="--dominant-color: #dad8d7;" loading="lazy" decoding="async" class="aligncenter wp-image-9369 size-medium not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram-300x166.avif" alt="" width="300" height="166" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram-300x166.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram-1024x567.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram-768x425.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram-1536x851.avif 1536w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-pinout-diagram.avif 1768w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<h3></h3>
<h3 data-start="139" data-end="157"><strong>ESP32-WROVER Module Variants</strong></h3>
<h4 data-start="162" data-end="191"><strong data-start="162" data-end="189">ESP32-WROVER / WROVER-I</strong></h4>
<ul>
<li data-start="197" data-end="295">The original module with integrated PSRAM (typically 4 MB)</li>
<li data-start="301" data-end="461"><strong data-start="301" data-end="313">WROVER-I</strong> refers to the version with a U.FL (IPEX) antenna connector (instead of or in addition to PCB trace antenna)</li>
</ul>
<h4 data-start="466" data-end="498"><strong data-start="466" data-end="496">ESP32-WROVER-B / WROVER-IB</strong></h4>
<ul>
<li data-start="504" data-end="626">These versions operate their PSRAM at 3.3 V (vs. 1.8 V in earlier WROVER versions)</li>
<li data-start="632" data-end="757">The “IB” suffix again implies the variant with an IPEX connector for external antenna</li>
</ul>
<h4 data-start="762" data-end="794"><strong data-start="762" data-end="792">ESP32-WROVER-E / WROVER-IE</strong></h4>
<ul>
<li data-start="800" data-end="931">A newer revision, often supporting larger flash or PSRAM variants (for example, 8 MB PSRAM)</li>
<li data-start="937" data-end="1043">The “IE” version includes the IPEX connector for external antennas</li>
</ul>
<h4 data-start="1048" data-end="1089"><strong data-start="1048" data-end="1087">Custom Flash / PSRAM configurations</strong></h4>
<ul>
<li data-start="1095" data-end="1267">Within each of these variants, you will often find options for different flash memory sizes (e.g. 4 MB, 8 MB, 16 MB) and PSRAM sizes</li>
<li data-start="1273" data-end="1426">Also, some modules may include or exclude onboard antenna or use external antenna connectors according to design.</li>
</ul>
<h3><strong>ESP32-WROVER Pinout Description</strong></h3>
<p>The ESP32-WROVER has the same pinout as the ESP32-WROOM. The pins are categorized into digital pins, analog pins, and power pins. Refer to the table below for details on pins with secondary functions. Moreover, these secondary pins often serve communication purposes, such as I2C and SPI or as ADC channels.</p>
<table>
<thead>
<tr>
<th class="tg-c6xy">Pin Name</th>
<th class="tg-c6xy">Description</th>
<th class="tg-c6xy">Pin Name</th>
<th class="tg-c6xy">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tg-1vgr">3V3</td>
<td class="tg-32oo">3.3   V power supply</td>
<td class="tg-1vgr">GND</td>
<td class="tg-32oo">Ground</td>
</tr>
<tr>
<td class="tg-bgrj">EN</td>
<td class="tg-a9jm">CHIP_PU,   Reset</td>
<td class="tg-bgrj">IO23</td>
<td class="tg-a9jm">GPIO23</td>
</tr>
<tr>
<td class="tg-1vgr">VP</td>
<td class="tg-32oo">GPIO36, ADC1_CH0, S_VP</td>
<td class="tg-1vgr">IO22</td>
<td class="tg-32oo">GPIO22</td>
</tr>
<tr>
<td class="tg-bgrj">VN</td>
<td class="tg-a9jm">GPIO39, ADC1_CH3, S_VN</td>
<td class="tg-bgrj">TX</td>
<td class="tg-a9jm">GPIO1, U0TXD</td>
</tr>
<tr>
<td class="tg-1vgr">IO34</td>
<td class="tg-32oo">GPIO34, ADC1_CH6, VDET_1</td>
<td class="tg-1vgr">RX</td>
<td class="tg-32oo">GPIO3, U0RXD</td>
</tr>
<tr>
<td class="tg-bgrj">IO35</td>
<td class="tg-a9jm">GPIO35, ADC1_CH7, VDET_2</td>
<td class="tg-bgrj">IO21</td>
<td class="tg-a9jm">GPIO21</td>
</tr>
<tr>
<td class="tg-1vgr">IO32</td>
<td class="tg-32oo">GPIO32, ADC1_CH4, TOUCH_CH9, XTAL_32K_P</td>
<td class="tg-1vgr">GND</td>
<td class="tg-32oo">Ground</td>
</tr>
<tr>
<td class="tg-bgrj">IO33</td>
<td class="tg-a9jm">GPIO33, ADC1_CH5, TOUCH_CH8, XTAL_32K_N</td>
<td class="tg-bgrj">IO19</td>
<td class="tg-a9jm">GPIO19</td>
</tr>
<tr>
<td class="tg-1vgr">IO25</td>
<td class="tg-32oo">GPIO25,   ADC1_CH8, DAC_1</td>
<td class="tg-1vgr">IO18</td>
<td class="tg-32oo">GPIO18</td>
</tr>
<tr>
<td class="tg-bgrj">IO26</td>
<td class="tg-a9jm">GPIO26,   ADC2_CH9, DAC_2</td>
<td class="tg-bgrj">IO5</td>
<td class="tg-a9jm">GPIO5</td>
</tr>
<tr>
<td class="tg-1vgr">IO27</td>
<td class="tg-32oo">GPIO27, ADC2_CH7, TOUCH_CH7</td>
<td class="tg-1vgr">IO17</td>
<td class="tg-a8im">GPIO17 3</td>
</tr>
<tr>
<td class="tg-bgrj">IO14</td>
<td class="tg-a9jm">GPIO14, ADC2_CH6, TOUCH_CH6, MTMS</td>
<td class="tg-bgrj">IO16</td>
<td class="tg-fb48">GPIO16 3</td>
</tr>
<tr>
<td class="tg-1vgr">IO12</td>
<td class="tg-32oo">GPIO12, ADC2_CH5, TOUCH_CH5, MTDI</td>
<td class="tg-1vgr">IO4</td>
<td class="tg-32oo">GPIO4, ADC2_CH0, TOUCH_CH0</td>
</tr>
<tr>
<td class="tg-bgrj">GND</td>
<td class="tg-a9jm">Ground</td>
<td class="tg-bgrj">IO0</td>
<td class="tg-a9jm">GPIO0, ADC2_CH1, TOUCH_CH1, Boot</td>
</tr>
<tr>
<td class="tg-1vgr">IO13</td>
<td class="tg-32oo">GPIO13, ADC2_CH4, TOUCH_CH4, MTCK</td>
<td class="tg-1vgr">IO2</td>
<td class="tg-32oo">GPIO2, ADC2_CH2, TOUCH_CH2</td>
</tr>
<tr>
<td class="tg-bgrj">D2</td>
<td class="tg-fb48">GPIO9, D2 2</td>
<td class="tg-bgrj">IO15</td>
<td class="tg-a9jm">GPIO15, ADC2_CH3, TOUCH_CH3, MTDO</td>
</tr>
<tr>
<td class="tg-1vgr">D3</td>
<td class="tg-a8im">GPIO10, D3 2</td>
<td class="tg-1vgr">D1</td>
<td class="tg-a8im">GPIO8, D1 2</td>
</tr>
<tr>
<td class="tg-bgrj">CMD</td>
<td class="tg-fb48">GPIO11, CMD 2</td>
<td class="tg-bgrj">D0</td>
<td class="tg-fb48">GPIO7, D0 2</td>
</tr>
<tr>
<td class="tg-1vgr">5V</td>
<td class="tg-32oo">5   V power supply</td>
<td class="tg-1vgr">CLK</td>
<td class="tg-a8im">GPIO6, CLK 2</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<h3><strong>ESP32 WROVER Schematic Diagram</strong></h3>
<p>The schematic diagram below is a useful reference, together with the pinout as you make your project.</p>
<p><em><a href="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic.avif">(Click to view larger image)</a><br />
<a href="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic.avif"><img data-dominant-color="f6f2f5" data-has-transparency="false" style="--dominant-color: #f6f2f5;" loading="lazy" decoding="async" class="aligncenter wp-image-9370 size-large not-transparent" src="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic-1024x558.avif" alt="" width="618" height="337" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic-1024x558.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic-300x163.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic-768x419.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2025/09/ESP32-WROVER-schematic.avif 1156w" sizes="auto, (max-width: 618px) 100vw, 618px" /></a><br />
</em></p>
<p>&nbsp;</p>
<p>Do you want some ESP32 project ideas? Check out the following tutorials:</p>
<ul>
<li><a href="https://www.teachmemicro.com/sensor-display-on-esp32-web-server/">Sensor Display on ESP32 Web Server</a></li>
<li><a href="https://www.teachmemicro.com/esp32-turbidity-sensor/">ESP32 Turbidity Sensor</a></li>
<li><a href="https://www.teachmemicro.com/esp32-magnetometer-hmc5883l/">ESP32 Magnetometer using HMC5883L</a></li>
<li><a href="https://www.teachmemicro.com/esp32-max7219-wifi-message-board/">ESP32 MAX7219 WiFi Message Board</a></li>
<li><a href="https://www.teachmemicro.com/esp32-restful-api/">Using Restful APIs with ESP32</a></li>
<li><a href="https://www.teachmemicro.com/esp32-pressure-sensor/">ESP32 Pressure Sensor</a></li>
</ul>
<p>... and many more! See our <a href="https://www.teachmemicro.com/category/tutorials/esp32-tutorial/">ESP32 Tutorial archive</a>.</p>
<p>The post <a href="https://www.teachmemicro.com/esp32-pinout-diagram-esp32-wrover/">ESP32 Pinout Diagram | ESP32-WROVER</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP12F Pinout Diagram</title>
		<link>https://www.teachmemicro.com/esp12f-pinout-diagram/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=esp12f-pinout-diagram</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 10 Feb 2025 12:49:24 +0000</pubDate>
				<category><![CDATA[Reference]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=8179</guid>

					<description><![CDATA[<p>The ESP-12F is an advanced version of the popular ESP8266 Wi-Fi module, offering improved RF performance and a compact design. Manufactured by Ai-Thinker, this module is ideal for IoT projects requiring wireless connectivity. Like its predecessor, the ESP-12F is built around the ESP8266EX chip, which features a 32-bit Tensilica L106 processor running at 80 MHz &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/esp12f-pinout-diagram/">ESP12F Pinout Diagram</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The <strong>ESP-12F</strong> is an advanced version of the popular ESP8266 Wi-Fi module, offering improved RF performance and a compact design. Manufactured by Ai-Thinker, this module is ideal for IoT projects requiring wireless connectivity.</p>
<p><span id="more-8179"></span></p>
<figure id="attachment_8181" aria-describedby="caption-attachment-8181" style="width: 300px" class="wp-caption aligncenter"><a href="https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram.avif"><img data-dominant-color="e6e3df" data-has-transparency="false" style="--dominant-color: #e6e3df;" loading="lazy" decoding="async" src="https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram-300x216.avif" alt="ESP12F pinout diagram" width="300" height="216" class="wp-image-8181 size-medium not-transparent" srcset="https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram-300x216.avif 300w, https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram-1024x737.avif 1024w, https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram-768x553.avif 768w, https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram.avif 1360w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a><figcaption id="caption-attachment-8181" class="wp-caption-text">                     <a href="https://www.teachmemicro.com/wp-content/uploads/2025/02/ESP12F-pinout-diagram.avif">Click to view full image</a></figcaption></figure>
<p>Like its predecessor, the ESP-12F is built around the <strong>ESP8266EX</strong> chip, which features a <strong>32-bit Tensilica L106 processor</strong> running at <strong>80 MHz (up to 160 MHz overclocked)</strong> and supports <strong>Wi-Fi 2.4 GHz (802.11 b/g/n)</strong>. With <strong>4 MB (32 Mbit) of flash memory</strong>, it is well-suited for applications like home automation, smart devices, and wireless sensors.</p>
<h3>ESP-12F Pin Description</h3>
<p>The ESP-12F has <strong>22 pins</strong>, including power, GPIOs, and communication interfaces. Below is a breakdown of the key pin functions:</p>
<h4><strong>ESP-12F Pinout Table</strong></h4>
<table>
<thead>
<tr>
<th><strong>Pin</strong></th>
<th><strong>Name</strong></th>
<th><strong>Function</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>RST</td>
<td>Reset (Active Low)</td>
</tr>
<tr>
<td>2</td>
<td>ADC (A0)</td>
<td>Analog Input (0–1V)</td>
</tr>
<tr>
<td>3</td>
<td>EN (CH_PD)</td>
<td>Chip Enable (Pull High for Normal Operation)</td>
</tr>
<tr>
<td>4</td>
<td>GPIO16</td>
<td>Wake from Deep Sleep, General Purpose I/O</td>
</tr>
<tr>
<td>5</td>
<td>GPIO14</td>
<td>SPI_CLK, General Purpose I/O</td>
</tr>
<tr>
<td>6</td>
<td>GPIO12</td>
<td>SPI_MISO, General Purpose I/O</td>
</tr>
<tr>
<td>7</td>
<td>GPIO13</td>
<td>SPI_MOSI, General Purpose I/O</td>
</tr>
<tr>
<td>8</td>
<td>VCC</td>
<td>3.3V Power Supply</td>
</tr>
<tr>
<td>9</td>
<td>GND</td>
<td>Ground</td>
</tr>
<tr>
<td>10</td>
<td>GPIO15</td>
<td>SPI_CS, Boot Mode Selection (Pull Low for Normal Operation)</td>
</tr>
<tr>
<td>11</td>
<td>GPIO2</td>
<td>Boot Mode Selection, General Purpose I/O</td>
</tr>
<tr>
<td>12</td>
<td>GPIO0</td>
<td>Boot Mode Selection (Pull Low for Flash Mode)</td>
</tr>
<tr>
<td>13</td>
<td>GPIO4</td>
<td>I²C SDA, General Purpose I/O</td>
</tr>
<tr>
<td>14</td>
<td>GPIO5</td>
<td>I²C SCL, General Purpose I/O</td>
</tr>
<tr>
<td>15</td>
<td>RXD (GPIO3)</td>
<td>UART0 RX, General Purpose I/O</td>
</tr>
<tr>
<td>16</td>
<td>TXD (GPIO1)</td>
<td>UART0 TX, General Purpose I/O</td>
</tr>
</tbody>
</table>
<h3>Boot Modes</h3>
<p>The ESP-12F supports different boot modes based on the state of GPIO0, GPIO2, and GPIO15:</p>
<table>
<thead>
<tr>
<th>Mode</th>
<th>GPIO0</th>
<th>GPIO2</th>
<th>GPIO15</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Normal Boot</td>
<td>High</td>
<td>High</td>
<td>Low</td>
<td>Runs firmware from flash</td>
</tr>
<tr>
<td>Flash Mode</td>
<td>Low</td>
<td>High</td>
<td>Low</td>
<td>Enables firmware flashing</td>
</tr>
</tbody>
</table>
<h3>Power Considerations</h3>
<p>The ESP-12F requires a <strong>stable 3.3V power supply</strong> and can draw up to <strong>170 mA</strong> during Wi-Fi transmissions. It is recommended to use an <strong>LDO voltage regulator</strong> or a <strong>dedicated power supply</strong> for reliable operation.</p>
<h3>Applications</h3>
<p>Due to its compact size, Wi-Fi capability, and low power consumption, the ESP-12F is commonly used in:</p>
<ul>
<li><strong>Smart home devices</strong> (e.g., Wi-Fi switches, sensors)</li>
<li><strong>IoT projects</strong></li>
<li><strong>Wireless data logging</strong></li>
<li><strong>Home automation systems</strong></li>
</ul>
<p>The post <a href="https://www.teachmemicro.com/esp12f-pinout-diagram/">ESP12F Pinout Diagram</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>STM32 I2C Calculator</title>
		<link>https://www.teachmemicro.com/stm32-i2c-calculator/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stm32-i2c-calculator</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Wed, 05 Feb 2025 01:40:35 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=8114</guid>

					<description><![CDATA[<p>I2C (Inter-Integrated Circuit) is a widely used communication protocol in embedded systems, particularly in STM32 microcontrollers. Configuring the correct clock settings for I2C communication is crucial for reliable data transmission. However, calculating the necessary parameters, such as the Clock Control Register (CCR), the Rise Time Register (TRISE), and the Timing Register in newer STM32 versions, &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/stm32-i2c-calculator/">STM32 I2C Calculator</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;">    <div class="box shadow  aligncenter" id="i2c-calculator">
        <label for="stm32-version">Select STM32 Version:</label>
        <select id="stm32-version">
            <option value="older">Older STM32 (CCR/TRISE)</option>
            <option value="newer">Newer STM32 (Timing Register)</option>
        </select>
        <label for="pclk">Peripheral Clock (PCLK) [Hz]:</label>
        <input type="number" id="pclk" placeholder="Enter PCLK frequency" />
        <label for="target_freq">Target I2C Frequency [Hz]:</label>
        <input type="number" id="target_freq" placeholder="Enter target frequency" />
        <button id="calculate-i2c">Calculate</button>
        <div id="i2c-results">
            <p><strong>RESULTS:</strong></p>
            <p><strong>CCR Register Value:</strong> <span id="ccr-value">N/A</span></p>
            <p><strong>TRISE Register Value:</strong> <span id="trise-value">N/A</span></p>
            <p><strong>Timing Register Value:</strong> <span id="timing-value">N/A</span></p>
        </div>
    </div>
    
<p data-pm-slice="1 1 []"><span>I2C (Inter-Integrated Circuit) is a widely used communication protocol in embedded systems, particularly in STM32 microcontrollers. Configuring the correct clock settings for I2C communication is crucial for reliable data transmission. However, calculating the necessary parameters, such as the Clock Control Register (CCR), the Rise Time Register (TRISE), and the Timing Register in newer STM32 versions, can be complex.</span></p>
<p><span>To simplify this process, we’ve developed an </span><span><strong>STM32 I2C Clock Calculator</strong></span><span>, which allows users to quickly determine the required settings based on the peripheral clock (PCLK) and the target I2C frequency. </span></p>
<h2><span>Understanding I2C Clock Configuration</span></h2>
<p><span>STM32 microcontrollers implement I2C timing configuration through different registers depending on the version:</span></p>
<ol data-spread="false" start="1">
<li><span><strong>CCR (Clock Control Register):</strong></span><span> Determines the clock period based on the PCLK and the desired I2C frequency (older STM32 models).</span></li>
<li><span><strong>TRISE (Rise Time Register):</strong></span><span> Ensures that the SDA and SCL lines meet the required timing constraints for correct signal transitions.</span></li>
<li><span><strong>Timing Register:</strong></span><span> Used in newer STM32 microcontrollers (such as STM32F7, STM32H7, and STM32L4) to configure I2C timing more precisely.</span></li>
</ol>
<h3><span>I2C Modes in STM32</span></h3>
<p><span>STM32 supports two primary I2C speed modes:</span></p>
<ul data-spread="false">
<li><span><strong>Standard Mode (SM):</strong></span><span> Operates at a maximum of 100 kHz.</span></li>
<li><span><strong>Fast Mode (FM):</strong></span><span> Operates up to 400 kHz.</span></li>
</ul>
<p><span>The formulas for computing CCR and TRISE values are as follows:</span></p>
<h4><span>Standard Mode (≤ 100 kHz)</span></h4>
<ul data-spread="false">
<li>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">CCR = PCLK / (2 * Target Frequency)</code></pre></pre>
</div>
</li>
<li>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">TRISE = (PCLK / 1,000,000) + 1</code></pre></pre>
</div>
</li>
</ul>
<h4><span>Fast Mode (≤ 400 kHz)</span></h4>
<ul data-spread="false">
<li>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">CCR = PCLK / (3 * Target Frequency)</code></pre></pre>
</div>
</li>
<li>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">TRISE = (PCLK / 1,000,000) * 300 / 1000 + 1</code></pre></pre>
</div>
</li>
</ul>
<p><span>For newer STM32 models, the </span><span><strong>Timing Register</strong></span><span> is used instead, requiring a more detailed calculation based on SCL timing constraints:</span></p>
<h4><span>Timing Register Calculation (Newer STM32 Versions)</span></h4>
<p><span>The Timing Register is composed of multiple fields:</span></p>
<ul data-spread="false">
<li><span><strong>SCLL (Low period of SCL clock):</strong></span><span></span>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">(PCLK / (2 * Target Frequency)) - 1</code></pre></pre>
</div>
</li>
<li><span><strong>SCLH (High period of SCL clock):</strong></span><span></span>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">(PCLK / (2 * Target Frequency)) - 1</code></pre></pre>
</div>
</li>
<li><span><strong>SDADEL (Data hold time):</strong></span><span></span>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">(PCLK / 100,000,000) (Approximate placeholder)</code></pre></pre>
</div>
</li>
<li><span><strong>SCLDEL (Data setup time):</strong></span><span></span>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">(PCLK / 50,000,000) (Approximate placeholder)</code></pre></pre>
</div>
</li>
</ul>
<p><span>The final </span><span><strong>Timing Register Value</strong></span><span> is calculated as:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-bash" data-lang="Bash"><pre><code class="language-cpp">TIMING = (SCLDEL &lt;&lt; 20) | (SDADEL &lt;&lt; 16) | (SCLH &lt;&lt; 8) | SCLL</code></pre></pre>
</div>
<p>&nbsp;</p>
<h2 data-pm-slice="1 3 []"><span>Using the STM32 I2C Clock Calculator</span></h2>
<p><span>This tool provides a user-friendly interface where you can:</span></p>
<ol data-spread="false" start="1">
<li><span>Select whether you are using an </span><span><strong>Older STM32 (CCR/TRISE)</strong></span><span> or </span><span><strong>Newer STM32 (Timing Register)</strong></span><span>.</span></li>
<li><span>Enter the Peripheral Clock (PCLK) in Hz.</span></li>
<li><span>Specify the Target I2C Frequency in Hz.</span></li>
<li><span>Click "Calculate" to obtain the necessary timing values.</span></li>
</ol>
<p>The post <a href="https://www.teachmemicro.com/stm32-i2c-calculator/">STM32 I2C Calculator</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Arduino UNO R4 WiFi LED Matrix Tool</title>
		<link>https://www.teachmemicro.com/arduino-uno-r4-led-matrix-tool/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=arduino-uno-r4-led-matrix-tool</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 10 Jan 2025 01:00:52 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7697</guid>

					<description><![CDATA[<p>The Arduino UNO R4 WiFi has a vibrant 12x8 LED matrix for creating visual patterns, animations, and more. To help you design and implement custom patterns for the LED matrix, we’ve developed a tool that simplifies the process.  This guide will walk you through how to use the tool and then incorporate your designs into &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/arduino-uno-r4-led-matrix-tool/">Arduino UNO R4 WiFi LED Matrix Tool</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span>The Arduino UNO R4 WiFi has a vibrant 12x8 LED matrix for creating visual patterns, animations, and more. To help you design and implement custom patterns for the LED matrix, we’ve developed a tool that simplifies the process.</span></p>
    <div id="led-matrix"></div>
    <div id="container">
        <div id="output-format">
            <label>
                <input type="checkbox" id="hex-output"> Hexadecimal Output
            </label>
        </div>
        <textarea id="code-output" readonly></textarea><br>
        <button class="button" id="copy-output" title="Copy to Clipboard">
                    <i class="fa fa-clipboard"></i>
        </button>
        <button class="button" id="export">Export</button>
        <input type="file" id="import" accept=".json">
    </div>
    
    
<p><span id="more-7697"></span></p>
<p><span> This guide will walk you through how to use the tool and then incorporate your designs into an Arduino project using the <em>Arduino_LED_Matrix.h</em></span><span><em> </em>library.</span></p>
<div>
<hr />
</div>
<h3><span><strong>Features of the Web Tool</strong></span></h3>
<ol data-spread="true" start="1">
<li><span><strong>Interactive Grid Interface</strong></span><span>:</span>
<ul data-spread="false">
<li><span>A 12x8 grid representing the LED matrix.</span></li>
<li><span>Each cell corresponds to an individual LED, and you can toggle it on or off.</span></li>
</ul>
</li>
<li><span><strong>Live Code Generation</strong></span><span>:</span>
<ul data-spread="false">
<li><span>Automatically generates an Arduino-compatible <em>byte</em></span><span> array based on your design.</span></li>
</ul>
</li>
<li><span><strong>Export and Import Functionality</strong></span><span>:</span>
<ul data-spread="false">
<li><span>Save your matrix designs as JSON files for future use.</span></li>
<li><span>Load previously saved designs back into the tool.</span></li>
</ul>
</li>
<li><span><strong>Visual Preview</strong></span><span>:</span>
<ul data-spread="false">
<li><span>See your LED pattern instantly as you create it.</span></li>
</ul>
</li>
</ol>
<div>
<hr />
</div>
<h3><span><strong>Step-by-Step Guide</strong></span></h3>
<h4><span>1. Access the Tool</span></h4>
<p><span>You’ll see a 12x8 grid of clickable cells representing the LEDs on the Arduino UNO R4’s matrix.</span></p>
<h4><span>2. Create Your Pattern</span></h4>
<ul data-spread="false">
<li><span>Click on any cell to toggle its state:</span>
<ul data-spread="false">
<li><span><strong>Green</strong></span><span>: The LED is turned on.</span></li>
<li><span><strong>Gray</strong></span><span>: The LED is turned off.</span></li>
</ul>
</li>
<li><span>Modify the grid until your desired pattern is complete.</span></li>
</ul>
<h4><span>3. Copy the Generated Code</span></h4>
<ul data-spread="false">
<li><span>As you create your pattern, the tool generates the corresponding C/C++ code in the following format:</span></li>
</ul>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">byte frame[8][12] = {
  { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
  { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
  { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
  { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
  { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};</code></pre></pre>
</div>
<ul data-spread="false">
<li><span>Copy the code directly from the tool’s output field.</span></li>
</ul>
<h4><span>4. Save or Load Patterns</span></h4>
<ul data-spread="false">
<li><span><strong>Export</strong></span><span>: Click the export button to download your design as a JSON file.</span></li>
<li><span><strong>Import</strong></span><span>: Load a previously saved design by selecting the JSON file via the import button.</span></li>
</ul>
<div>
<hr />
</div>
<h3><span><strong>Integrating with Arduino</strong></span></h3>
<p><span>To use your generated pattern on the Arduino UNO R4, we recommend the <em>Arduino_LED_Matrix.h</em></span><span> library. Follow these steps to bring your pattern to life:</span></p>
<h4><span>1. Install the Library</span></h4>
<ul data-spread="false">
<li><span>Open the Arduino IDE.</span></li>
<li><span>Go to </span><span><strong>Sketch &gt; Include Library &gt; Manage Libraries</strong></span><span>.</span></li>
<li><span>Search for <em>Arduino_LED_Matrix</em></span><span> and click </span><span><strong>Install</strong></span><span>.</span></li>
</ul>
<h4><span>2. Setup the Hardware</span></h4>
<p><span>Ensure your Arduino UNO R4 WiFi is powered and the LED matrix is properly initialized. The library handles all low-level configurations for you.</span></p>
<h4><span>3. Upload the Code</span></h4>
<p><span>Use the following example code to display your pattern:</span></p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;Arduino_LED_Matrix.h&gt;

ArduinoLEDMatrix matrix;

byte frame[8][12] = {
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
  { 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0 }
};

void setup() {
    matrix.begin();
    matrix.renderBitmap(frame, 8, 12);
}

void loop() {
    // Add animations or additional logic here
}</code></pre></pre>
</div>
<p>You can also use a hexadecimal output by checking the box in the tool. This will reduce memory usage because you are now using a 32-bit variable instead of several bytes.<br />
This code will produce the same glyph as the code above:</p>
<div class="hcb_wrap">
<pre class="prism undefined-numbers lang-cpp" data-lang="C++"><pre><code class="language-cpp">#include &lt;Arduino_LED_Matrix.h&gt;

ArduinoLEDMatrix matrix;

unsigned long frame[] = {
  0x60660660,
  0x67fe7fe6,
  0x06606606
};

void setup() {
    matrix.begin();
    matrix.loadFrame(frame);
}

void loop() {
    // Add animations or additional logic here
}</code></pre></pre>
</div>
<h4><span>4. Modify and Test</span></h4>
<ul data-spread="false">
<li><span>Upload the sketch to your Arduino.</span></li>
<li><span>Observe your custom pattern light up on the LED matrix!</span></li>
</ul>
<div>
<hr />
</div>
<h3>Tips and Tricks</h3>
<ul data-spread="false">
<li><span><strong>Animations</strong></span><span>: To create animations, define multiple <em>frame </em></span><span>arrays and cycle through them in the <em>loop()</em></span><span> function.</span></li>
<li><span><strong>Brightness Control</strong></span><span>: Use the library’s brightness functions to adjust the LED intensity.</span></li>
<li><span><strong>Dynamic Patterns</strong></span><span>: Combine inputs like buttons or sensors to dynamically modify the displayed pattern.</span></li>
</ul>
<div>
<hr />
</div>
<p><span>With this tool and guide, you can easily design and program patterns for your Arduino UNO R4’s LED matrix. Have fun experimenting, and bring your ideas to light!</span></p>
<p>The post <a href="https://www.teachmemicro.com/arduino-uno-r4-led-matrix-tool/">Arduino UNO R4 WiFi LED Matrix Tool</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Dot Matrix Glyph Creator Online</title>
		<link>https://www.teachmemicro.com/dot-matrix-glyph-creator-online/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=dot-matrix-glyph-creator-online</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 30 Dec 2024 04:14:17 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7619</guid>

					<description><![CDATA[<p>Dot matrix displays are a staple in microcontroller projects, offering a versatile way to showcase custom graphics, animations, and messages. Whether you're working with an Arduino, Raspberry Pi, ESP32, ESP8266, or STM32, creating dot matrix glyphs no longer needs to be a time-consuming task. This article introduces an intuitive tool that allows you to design &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/dot-matrix-glyph-creator-online/">Dot Matrix Glyph Creator Online</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Dot matrix displays are a staple in microcontroller projects, offering a versatile way to showcase custom graphics, animations, and messages. Whether you're working with an Arduino, Raspberry Pi, ESP32, ESP8266, or STM32, creating dot matrix glyphs no longer needs to be a time-consuming task. This article introduces an intuitive tool that allows you to design custom dot matrix glyphs and generate Arduino-compatible code with ease.</p>
    
    <div id="dot-matrix-tool">
        <label for="matrix-width">Matrix Width:</label>
        <select id="matrix-width">
            <option value="8">8</option>
            <option value="16">16</option>
            <option value="32">32</option>
        </select>
        <label for="matrix-height">Matrix Height:</label>
        <select id="matrix-height">
            <option value="8">8</option>
            <option value="16">16</option>
            <option value="32">32</option>
        </select>
        <button class="button" id="apply-settings">Apply</button>
        <div id="dot-matrix-grid"></div>
        <br>
        <button class="button" id="generate-code">Generate Code</button>
        <br><br>
        <textarea id="arduino-code" readonly></textarea>
    </div>
    
<p><span id="more-7619"></span></p>
<hr />
<h3><strong>What Is the Dot Matrix Glyph Creator?</strong></h3>
<p>The Dot Matrix Glyph Creator is an interactive tool designed to streamline the process of creating graphics for dot matrix displays. With a visual grid interface, users can toggle individual dots to create custom designs and instantly generate the corresponding code for use in microcontroller projects.</p>
<hr />
<h3><strong>Why Use This Tool?</strong></h3>
<h4><strong>1. Save Time on Graphics Design</strong></h4>
<p>Creating dot matrix glyphs manually can be tedious and prone to errors. This tool eliminates the need for manual calculations, providing a straightforward interface for designing custom patterns.</p>
<h4><strong>2. Multi-Platform Compatibility</strong></h4>
<p>The tool generates code compatible with MAX7219 libraries, ensuring seamless integration with platforms like Arduino, Raspberry Pi, ESP32, ESP8266, and STM32.</p>
<h4><strong>3. Flexible Grid Sizes</strong></h4>
<p>With support for commonly used grid dimensions like 8x8, 16x16, and 32x32, this tool adapts to various dot matrix display configurations.</p>
<hr />
<h3><strong>Features of the Dot Matrix Glyph Creator</strong></h3>
<h4><strong>Interactive Design Interface</strong></h4>
<p>The tool features a grid where each dot can be toggled between "on" (lit) and "off" (unlit). Unlit dots appear as black, while lit dots are represented in dark orange to mimic the appearance of an actual dot matrix display.</p>
<h4><strong>Customizable Grid Dimensions</strong></h4>
<p>Users can select the matrix width and height (e.g., 8x8, 16x16) from a dropdown menu, and the grid dynamically adjusts to the chosen dimensions.</p>
<h4><strong>Real-Time Code Generation</strong></h4>
<p>After designing a glyph, a simple click generates the corresponding code, ready to be copied and pasted into your project. The output is compatible with MAX7219 library functions, such as:</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 glyph[8] = { 0x3C, 0x42, 0x81, 0xA1, 0x81, 0x42, 0x3C, 0x00 };</code></pre></pre>
</div>
</div>
</div>
<h4><strong>Realistic Dot Representation</strong></h4>
<p>The grid uses circular dots with smooth transitions between states, simulating the look of a physical dot matrix display.</p>
<h4><strong>Responsive Design</strong></h4>
<p>The tool is fully responsive, ensuring an optimal experience across desktops, tablets, and smartphones.</p>
<hr />
<h2><strong>Who Can Benefit from This Tool?</strong></h2>
<ul>
<li><strong>Hobbyists and Makers:</strong> Perfect for those building fun and creative projects with Arduino or Raspberry Pi.</li>
<li><strong>Educators and Students:</strong> A hands-on way to teach and learn how dot matrix displays work.</li>
<li><strong>IoT Developers:</strong> Ideal for creating custom graphics in ESP32 or ESP8266-based projects.</li>
<li><strong>Embedded Engineers:</strong> Simplifies graphic design for STM32-based systems and beyond.</li>
</ul>
<hr />
<h2><strong>Conclusion</strong></h2>
<p>The Dot Matrix Glyph Creator is a game-changing tool for anyone working with MAX7219 displays. Its intuitive interface, customizable grid, and instant code generation make it an invaluable resource for designing professional-grade graphics in a fraction of the time. Whether you're a hobbyist, educator, or engineer, this tool is here to simplify your workflow and inspire your creativity.</p>
<p>Start creating stunning dot matrix glyphs today and bring your microcontroller projects to life!</p>
<p>The post <a href="https://www.teachmemicro.com/dot-matrix-glyph-creator-online/">Dot Matrix Glyph Creator Online</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>LCD Bitmap Converter Online</title>
		<link>https://www.teachmemicro.com/lcd-bitmap-converter-online/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lcd-bitmap-converter-online</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Mon, 30 Dec 2024 02:25:58 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7610</guid>

					<description><![CDATA[<p>Looking for an easy way to convert an image into LCD bitmap data? This LCD bitmap converter lets you upload a JPG, PNG, or BMP image and generate a C/C++ array for Arduino, STM32, ESP32, Raspberry Pi Pico, and other microcontroller projects. Because the tool runs in your browser, there is nothing to install. As &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/lcd-bitmap-converter-online/">LCD Bitmap Converter Online</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Looking for an easy way to convert an image into LCD bitmap data? This LCD bitmap converter lets you upload a JPG, PNG, or BMP image and generate a C/C++ array for Arduino, STM32, ESP32, Raspberry Pi Pico, and other microcontroller projects.</p>
<p>Because the tool runs in your browser, there is nothing to install. As a result, you can quickly create icons, logos, symbols, splash screens, and simple display graphics for LCD, OLED, and TFT modules.</p>
        <div id="lcd-tool">
            <div id="lcd-settings">
                <label>
                    Horizontal Pixels:
                    <input type="number" id="horizontal-pixels" value="128" min="8" step="8" />
                </label>
                <label>
                    Vertical Pixels:
                    <input type="number" id="vertical-pixels" value="64" min="8" step="8" />
                </label>
                <button class="button" id="set-resolution">Set Resolution</button>
            </div>
            <div id="controls">
              <label class="controls-lcd-bitmap">
                <input type="checkbox" id="color-mode" />
                Enable Color Mode
              </label>
              <label class="controls-lcd-bitmap" for="reverse-bits">
                <input type="checkbox" id="reverse-bits">
                Reverse bits (LSB first)
              </label>
            </div>
            <br>
            <div id="lcd-image-upload">
                <label>
                    Upload Image:
                <input type="file" id="image-input" accept="image/*" />
                </label>
            </div>
            <div class="lcd-grid-scroll">
                <div id="lcd-grid"></div>
            </div>
            <br>
            <button class="button" id="export-btn">Export Bitmap</button>
            <br><br>
            <div id="lcd-output-container">
              <textarea id="lcd-output" readonly></textarea>
              <div class="grid-container">
                  <button id="copy-output" title="Copy to Clipboard">
                    <i class="fa fa-clipboard"></i>
                  </button>
                  <button id="clear-output" title="Clear Output">
                    <i class="fa fa-eraser"></i>
                  </button>
              </div>
            </div>
        </div>
    
<h2 id="what-is-an-lcd-bitmap-converter-"><strong>What Is an LCD Bitmap Converter?</strong></h2>
<p>An LCD bitmap converter turns an image into pixel data that a microcontroller can display on a screen. Instead of manually writing hexadecimal values, you upload or draw an image, choose the display size, and let the tool generate the array for your code.</p>
<p>This is useful when working with displays such as:</p>
<ul>
<li>128x64 monochrome LCDs</li>
<li>128x32 and 128x64 OLED displays</li>
<li>160x128 TFT displays</li>
<li>240x240 TFT displays</li>
<li>320x240 TFT displays</li>
<li>Custom graphical LCD modules</li>
</ul>
<p>After conversion, the generated output can be copied into Arduino sketches, STM32 projects, ESP32 firmware, or other embedded C/C++ programs.</p>
<h2 id="key-features"><strong>Key Features</strong></h2>
<h3 id="upload-an-image-and-convert-it"><strong>Upload an Image and Convert It</strong></h3>
<p>First, upload a JPG, PNG, or BMP image. Then, the tool converts it into bitmap data for your display. It maps the image to your selected resolution, so you can preview how it will appear on the LCD or OLED screen.</p>
<p>After that, you can still edit the pixels before generating the final code. This is helpful if the automatic conversion needs small adjustments.</p>
<h3 id="draw-directly-on-the-pixel-grid"><strong>Draw Directly on the Pixel Grid</strong></h3>
<p>You can also create a bitmap from scratch using the interactive pixel grid. Simply click each square to turn a pixel on or off.</p>
<p>Because each pixel can be edited manually, this mode is useful for simple icons, arrows, battery symbols, menu graphics, and small logos.</p>
<h3 id="set-a-custom-display-resolution"><strong>Set a Custom Display Resolution</strong></h3>
<p>Before drawing or converting an image, enter the width and height of your display. This helps the output match your actual screen.</p>
<p>Common resolutions include:</p>
<ul>
<li><a href="https://www.teachmemicro.com/arduino-nokia-3310-lcd-interfacing/">128x64 for monochrome graphical LCDs and OLEDs</a></li>
<li><a href="https://www.teachmemicro.com/0-96-tiny-oled-display-arduino/">128x32 for small OLED modules</a></li>
<li>160x128 for compact TFT displays</li>
<li>240x240 for square TFT displays</li>
<li>320x240 for larger TFT LCD screens</li>
</ul>
<p>For best results, use the same resolution as your actual display.</p>
<h3 id="generate-c-and-c-bitmap-arrays"><strong>Generate C and C++ Bitmap Arrays</strong></h3>
<p>Once your graphic is ready, click Generate to create a C/C++ array. The output is formatted so you can paste it directly into your firmware.</p>
<p>Example output:</p>
<pre><code class="lang-c">const uint8_t bitmap[] = {
  <span class="hljs-number">0xFF</span>, <span class="hljs-number">0x81</span>, <span class="hljs-number">0x81</span>, <span class="hljs-number">0xFF</span>
};
</code></pre>
<p>Depending on your display type and library, this array can be used to draw the bitmap on the screen.</p>
<h3 id="copy-the-code-quickly"><strong>Copy the Code Quickly</strong></h3>
<p>After generating the array, use the Copy button to copy the code to your clipboard. Then, paste it into your Arduino, STM32, ESP32, or other embedded project. This makes the workflow faster, especially when testing several icons or display graphics.</p>
<h2 id="how-to-use-the-lcd-bitmap-converter"><strong>How to Use the LCD Bitmap Converter</strong></h2>
<h3 id="1-set-the-display-size"><strong>1. Set the Display Size</strong></h3>
<p>First, enter the width and height of your LCD, OLED, or TFT display. For example, use 128x64 if you are working with a common monochrome OLED screen.</p>
<h3 id="2-choose-the-display-mode"><strong>2. Choose the Display Mode</strong></h3>
<p>Next, select the mode that matches your display. Use monochrome mode for simple black-and-white LCDs or OLEDs. Meanwhile, use color mode for TFT display graphics.</p>
<h3 id="3-draw-or-upload-an-image"><strong>3. Draw or Upload an Image</strong></h3>
<p>After setting the display size, you can draw directly on the grid or upload an existing image. For best results, use a simple high-contrast image, icon, or logo.</p>
<h3 id="4-preview-and-edit-the-bitmap"><strong>4. Preview and Edit the Bitmap</strong></h3>
<p>Then, check the converted image on the grid. If some pixels do not look right, edit them manually before generating the array.</p>
<h3 id="5-generate-the-c-array"><strong>5. Generate the C Array</strong></h3>
<p>Once the bitmap looks correct, click Generate to create the bitmap data. The tool will output a C/C++ array that you can use in your microcontroller code.</p>
<h3 id="6-copy-and-paste-into-your-project"><strong>6. Copy and Paste Into Your Project</strong></h3>
<p>Finally, copy the generated code and paste it into your firmware. Then, use your display library to draw the bitmap on the screen.</p>
<h2 id="supported-display-types"><strong>Supported Display Types</strong></h2>
<h3 id="monochrome-lcd-displays"><strong>Monochrome LCD Displays</strong></h3>
<p>The tool works well with monochrome graphical LCDs, especially displays that use simple on/off pixel data. These are common in menus, meters, embedded control panels, and industrial devices.</p>
<h3 id="oled-displays"><strong>OLED Displays</strong></h3>
<p>You can use the converter for small OLED screens, including common 128x32 and 128x64 modules used with Arduino, ESP32, and STM32 boards.</p>
<h3 id="tft-lcd-displays"><strong>TFT LCD Displays</strong></h3>
<p>For color display projects, the tool can help prepare image data for TFT modules such as 160x128, 240x240, and 320x240 displays.</p>
<h2 id="microcontroller-projects"><strong>Microcontroller Projects</strong></h2>
<p>Because the output is a C/C++ array, it can be used in many embedded projects, including:</p>
<ul>
<li>Arduino display projects</li>
<li>ESP32 dashboards</li>
<li>STM32 user interfaces</li>
<li>Raspberry Pi Pico display projects</li>
<li>Sensor menus</li>
<li>IoT status screens</li>
<li>Handheld devices</li>
<li>Custom electronics projects</li>
</ul>
<h2 id="tips-for-better-bitmap-results"><strong>Tips for Better Bitmap Results</strong></h2>
<p>Use simple images with strong contrast. Small LCD and OLED screens have limited resolution, so detailed photos may not convert clearly. Resize the image before uploading if needed. A small icon usually looks better than a large image forced into a tiny display area. For monochrome displays, use black-and-white artwork whenever possible. This makes the converted bitmap easier to read on the screen. For logos and icons, test different sizes until the shape remains clear at your display resolution.</p>
<h2 id="why-use-an-online-lcd-image-converter-"><strong>Why Use an Online LCD Image Converter?</strong></h2>
<p>An online LCD image converter saves time when creating graphics for embedded systems. You do not need to install separate bitmap software or manually calculate hex values.</p>
<p>This tool gives you a simple workflow:</p>
<ol>
<li>Upload or draw an image.</li>
<li>Preview the bitmap.</li>
<li>Generate the C/C++ array.</li>
<li>Copy the code into your project.</li>
</ol>
<p>As a result, it becomes easier to add icons, logos, and custom graphics to your LCD, OLED, or TFT display project.</p>
<h2><strong>FAQs</strong></h2>
<h3><strong>Can I use this LCD bitmap converter with Arduino?</strong></h3>
<p>Yes. The generated C/C++ array can be copied into Arduino sketches and used with compatible display libraries.</p>
<h3><strong>Can this convert images for OLED displays?</strong></h3>
<p>Yes. It can be used for common OLED resolutions such as 128x32 and 128x64.</p>
<h3><strong>What image format should I upload?</strong></h3>
<p>Use JPG, PNG, or BMP. For best results, use simple high-contrast images.</p>
<h2 id="try-the-lcd-bitmap-converter"><strong>Try the LCD Bitmap Converter</strong></h2>
<p>Use the tool above to create your LCD bitmap online. First, set your display size. Then, upload or draw your image. Finally, generate the C/C++ array and paste the result into your microcontroller code.</p>
<p>The post <a href="https://www.teachmemicro.com/lcd-bitmap-converter-online/">LCD Bitmap Converter Online</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>STM32 CAN Bus Configuration Calculator</title>
		<link>https://www.teachmemicro.com/stm32-can-bus-configuration-calculator/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stm32-can-bus-configuration-calculator</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Fri, 27 Dec 2024 00:43:46 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7592</guid>

					<description><![CDATA[<p>This CAN Bus calculator will help you calculate the configuration values given the desired bit rate and system clock frequency. Understanding STM32 CAN Bus and Configuration Calculations The Controller Area Network (CAN) bus is a robust communication protocol widely used in automotive, industrial, and embedded systems. STM32 microcontrollers support CAN communication, providing developers with a &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/stm32-can-bus-configuration-calculator/">STM32 CAN Bus Configuration Calculator</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This CAN Bus calculator will help you calculate the configuration values given the desired bit rate and system clock frequency.</p>
<div class="box shadow  aligncenter" style="width:600px"><div class="box-inner-block"><i class="fa tie-shortcode-boxicon"></i>
			    <div class="can-bus-calculator">
        <form id="can-bus-calculator-form">
            <label for="can-clock">CAN Clock Frequency (Hz):</label>
            <input type="number" id="can-clock" name="can-clock" min="1" required>

            <label for="bit-rate">Desired Bit Rate (bps):</label>
            <input type="number" id="bit-rate" name="bit-rate" min="1" required>

            <button type="button" id="calculate-button">Calculate</button>
        </form>
        <div id="results">
            <p><strong>Prescaler:</strong> <span id="prescaler"></span></p>
            <p><strong>Time Segments:</strong> <span id="time-segments"></span></p>
        </div>
    </div>
    
			</div></div>
<p><span id="more-7592"></span></p>
<p data-pm-slice="1 1 []"><span><strong>Understanding STM32 CAN Bus and Configuration Calculations</strong></span></p>
<p><span>The Controller Area Network (CAN) bus is a robust communication protocol widely used in automotive, industrial, and embedded systems. STM32 microcontrollers support CAN communication, providing developers with a versatile platform for implementing networked solutions. Configuring the CAN bus in STM32 involves calculating specific parameters that ensure proper communication between devices. This article explains the basics of the CAN bus and details the process of calculating the configuration values for STM32.</span></p>
<div>
<hr />
</div>
<h3><span><strong>What is the CAN Bus?</strong></span></h3>
<p><span>The CAN bus is a two-wire communication protocol that enables microcontrollers and devices to communicate without a host computer. Key features include:</span></p>
<ul data-spread="false">
<li><span><strong>Real-time communication</strong></span><span>: Ensures deterministic message delivery.</span></li>
<li><span><strong>Error detection</strong></span><span>: Built-in mechanisms ensure reliable data transmission.</span></li>
<li><span><strong>Priority-based messaging</strong></span><span>: Messages with higher priority are transmitted first.</span></li>
</ul>
<p><span>In an STM32 system, the CAN peripheral handles message transmission and reception, while configuration values define the timing and operation of the CAN bus.</span></p>
<div>
<hr />
</div>
<h3><span><strong>CAN Bus Timing and Configuration Parameters</strong></span></h3>
<p><span>The CAN bus operates using a clock signal divided into time quanta (TQ), the smallest unit of time used in CAN bit timing. A single bit period consists of:</span></p>
<ol data-spread="false" start="1">
<li><span><strong>Synchronization Segment (Sync_Seg):</strong></span><span> Fixed at 1 TQ, marking the start of the bit.</span></li>
<li><span><strong>Propagation Segment (Prop_Seg):</strong></span><span> Compensates for signal propagation delay.</span></li>
<li><span><strong>Phase Segment 1 (Phase_Seg1):</strong></span><span> Adjusts to synchronize the clock.</span></li>
<li><span><strong>Phase Segment 2 (Phase_Seg2):</strong></span><span> Ensures the bit ends correctly.</span></li>
</ol>
<p><span>The total time quanta (TQ) for a bit period is:</span></p>
<p><span>The configuration parameters for STM32 CAN bus include:</span></p>
<ul data-spread="false">
<li><span><strong>Bit Timing Prescaler (BRP):</strong></span><span> Divides the input clock to produce the CAN clock.</span></li>
<li><span><strong>Time Segment 1 (TS1):</strong></span><span> Sum of Prop_Seg and Phase_Seg1.</span></li>
<li><span><strong>Time Segment 2 (TS2):</strong></span><span> Corresponds to Phase_Seg2.</span></li>
</ul>
<div>
<hr />
</div>
<h3><span><strong>Steps to Calculate STM32 CAN Configuration</strong></span></h3>
<h4><span>1. </span><span><strong>Determine the Input Clock</strong></span></h4>
<p><span>The CAN peripheral uses the APB clock of the STM32 microcontroller. Identify this clock frequency, typically defined in the microcontroller’s configuration settings.</span></p>
<h4><span>2. </span><span><strong>Define the Desired Bit Rate</strong></span></h4>
<p><span>The desired bit rate determines how fast the CAN bus transmits data, measured in bits per second (bps). Common values are 125 kbps, 250 kbps, and 1 Mbps.</span></p>
<h4><span>3. </span><span><strong>Calculate the Bit Period</strong></span></h4>
<p><span>The bit period is the reciprocal of the bit rate:</span></p>
<h4><span>4. </span><span><strong>Choose the Total Time Quanta (TQ_total)</strong></span></h4>
<p><span>Select an appropriate number of TQ for the bit period. CAN standards recommend values between 8 and 25 TQ.</span></p>
<h4><span>5. </span><span><strong>Calculate the Baud Rate Prescaler (BRP)</strong></span></h4>
<p><span>The BRP divides the input clock to match the CAN clock. Calculate BRP using:</span></p>
<p><span>Round BRP to the nearest integer, ensuring it stays within the allowable range (1 to 1024 for STM32).</span></p>
<h4><span>6. </span><span><strong>Distribute Time Quanta</strong></span></h4>
<p><span>Divide the remaining TQ among Prop_Seg, Phase_Seg1, and Phase_Seg2 while adhering to the following rules:</span></p>
<ul data-spread="false">
<li><span>TS1 (Prop_Seg + Phase_Seg1) should be 75-87.5% of TQ_total.</span></li>
<li><span>TS2 (Phase_Seg2) should be 12.5-25% of TQ_total.</span></li>
</ul>
<div>
<hr />
</div>
<h3><span><strong>Example Calculation</strong></span></h3>
<p><span>Suppose:</span></p>
<ul data-spread="false">
<li><span>Input Clock = 36 MHz</span></li>
<li><span>Desired Bit Rate = 500 kbps</span></li>
</ul>
<ol data-spread="true" start="1">
<li><span><strong>Calculate Bit Period:</strong></span><span> </span></li>
<li><span><strong>Choose TQ_total:</strong></span><span> Assume 16 TQ. </span></li>
<li><span><strong>Calculate BRP:</strong></span><span> </span><span> Round to 4.</span></li>
<li><span><strong>Distribute TQ:</strong></span></li>
</ol>
<ul data-spread="false">
<li><span>TS1 = 13 TQ (includes Prop_Seg and Phase_Seg1)</span></li>
<li><span>TS2 = 2 TQ</span></li>
<li><span>Sync_Seg = 1 TQ</span></li>
</ul>
<div>
<hr />
</div>
<h3><span><strong>Verifying Configuration</strong></span></h3>
<p><span>STM32CubeMX or similar tools can validate your configuration. Alternatively, calculate the actual bit rate:</span></p>
<p><span>Ensure the calculated value closely matches the desired bit rate.</span></p>
<div>
<hr />
</div>
<h3><span><strong>Common Pitfalls</strong></span></h3>
<ol data-spread="false" start="1">
<li><span><strong>Clock Mismatches:</strong></span><span> Ensure the input clock matches the actual APB clock frequency.</span></li>
<li><span><strong>Invalid Configurations:</strong></span><span> Keep TS1 and TS2 within recommended ranges.</span></li>
<li><span><strong>Error Tolerance:</strong></span><span> The calculated bit rate should be within 1% of the desired value.</span></li>
</ol>
<div>
<hr />
</div>
<h3><span><strong>Conclusion</strong></span></h3>
<p><span>Configuring the CAN bus on STM32 requires careful calculation of timing parameters to ensure reliable communication. By understanding the principles behind bit timing and using tools like STM32CubeMX, you can efficiently set up the CAN peripheral for your application. Whether you're working on automotive networks or embedded systems, mastering CAN configuration is a valuable skill for any STM32 developer.</span></p>
<p>The post <a href="https://www.teachmemicro.com/stm32-can-bus-configuration-calculator/">STM32 CAN Bus Configuration Calculator</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>STM32 PWM Calculator</title>
		<link>https://www.teachmemicro.com/stm32-pwm-calculator/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=stm32-pwm-calculator</link>
		
		<dc:creator><![CDATA[Roland Pelayo]]></dc:creator>
		<pubDate>Thu, 26 Dec 2024 23:28:28 +0000</pubDate>
				<category><![CDATA[Tools]]></category>
		<guid isPermaLink="false">https://www.teachmemicro.com/?p=7582</guid>

					<description><![CDATA[<p>This calculator will help you compute the desired PWM frequency. Just put in the clock frequency and the desired PWM frequency and click the "calculate" button. The prescaler value and the ARR (auto-reload register value) will be the results. What is PWM? Pulse Width Modulation (PWM) is a technique used to generate analog-like signals from &#8230;</p>
<p>The post <a href="https://www.teachmemicro.com/stm32-pwm-calculator/">STM32 PWM Calculator</a> appeared first on <a href="https://www.teachmemicro.com">Microcontroller Tutorials</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>This calculator will help you compute the desired PWM frequency. Just put in the clock frequency and the desired PWM frequency and click the "calculate" button. The prescaler value and the ARR (auto-reload register value) will be the results.</p>
<div class="box shadow  aligncenter" style="width:600px"><div class="box-inner-block"><i class="fa tie-shortcode-boxicon"></i>
			    <div class="stm32_pwm_calculator">
        <div class="input-group">
        <label for="systemClock">System Clock Frequency (Hz):</label>
        <input type="text" id="systemClock" placeholder="Enter system clock frequency in Hz">
    </div>
    <div class="input-group">
        <label for="desiredFrequency">Desired PWM Frequency (Hz):</label>
        <input type="text" id="desiredFrequency" placeholder="Enter desired PWM frequency in Hz">
    </div>
    <button type="button" id="calculate">Calculate ARR and Prescaler</button>
    <div class="result" id="result"></div>
    </div>

    
			</div></div>
<p><span id="more-7582"></span></p>
<h3><strong>What is PWM?</strong></h3>
<p>Pulse Width Modulation (PWM) is a technique used to generate analog-like signals from a digital source by varying the duty cycle of a square wave. It is widely used in applications like motor control, LED brightness control, and audio signal generation.</p>
<p>In STM32 microcontrollers, PWM signals are typically generated using timers. The timers divide the clock frequency and configure the output pins to create the desired frequency and duty cycle.</p>
<p>&nbsp;</p>
<h3>Key Concepts of STM32 PWM</h3>
<ol>
<li><strong>System Clock Frequency</strong>:<br />
This is the main clock frequency driving the microcontroller, which serves as the base clock for the timers.</li>
<li><strong>Prescaler</strong>:<br />
A value that divides the timer input clock. For example, if the system clock is 72 MHz and the prescaler is set to 71, the timer clock will be <span class="katex"><span class="katex"><span class="katex-mathml"> <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mrow><mn>72</mn><mtext> </mtext><mtext>MHz</mtext></mrow><mrow><mo stretchy="false">(</mo><mn>71</mn><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mfrac><mo>=</mo><mn>1</mn><mtext> </mtext><mtext>MHz</mtext></mrow><annotation encoding="application/x-tex">\frac{72 \, \text{MHz}}{(71+1)} = 1 \, \text{MHz}</annotation></semantics></math></span></span></span>&nbsp;</p>
<p>.</li>
<li><strong>Auto-Reload Register (ARR)</strong>:<br />
Also known as the timer period, this defines how many timer clock cycles occur before the timer resets and the signal toggles. A higher ARR results in a lower frequency.</li>
<li><strong>Duty Cycle</strong>:<br />
This is the percentage of time the signal stays HIGH during one period. The duty cycle is controlled by the <strong>Capture/Compare Register (CCR)</strong> in STM32.</li>
</ol>
<hr />
<h3>Formula to Calculate PWM Frequency</h3>
<p>The PWM frequency can be calculated using the formula:</p>
<p><span class="katex-display"><span class="katex"><span class="katex-mathml"></span></span></span></p>
<p><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>PWM Frequency</mtext><mo>=</mo><mfrac><mtext>System Clock Frequency</mtext><mrow><mo stretchy="false">(</mo><mtext>Prescaler</mtext><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>×</mo><mo stretchy="false">(</mo><mtext>ARR</mtext><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></mfrac></mrow><annotation encoding="application/x-tex">\text{PWM Frequency} = \frac{\text{System Clock Frequency}}{(\text{Prescaler} + 1) \times (\text{ARR} + 1)}</annotation></semantics></math></p>
<p><span class="katex-html" aria-hidden="true"><span class="base"><span class="mord"><span class="mfrac"><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist-s">​</span></span><span class="vlist-r"><span class="vlist"><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span></span></p>
<p>Where:</p>
<ul>
<li><strong>System Clock Frequency</strong>: The frequency of the system clock driving the timer (e.g., 72 MHz for many STM32 devices).</li>
<li><strong>Prescaler</strong>: The value used to divide the clock frequency.</li>
<li><strong>ARR (Auto-Reload Register)</strong>: The maximum count value for the timer.</li>
</ul>
<hr />
<h3>Example Calculation</h3>
<p><strong>Scenario</strong>:<br />
You have an STM32 microcontroller with the following parameters:</p>
<ul>
<li>System Clock Frequency: <span class="katex"><span class="katex"><span class="katex-mathml"><br />
<math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>72</mn><mtext> </mtext><mtext>MHz</mtext></mrow><annotation encoding="application/x-tex">72 \, \text{MHz}</annotation></semantics></math></span></span></span>&nbsp;</p>
<p><span class="katex"><span class="katex-mathml"></span><br />
</span></li>
<li>Timer Prescaler: <span class="katex"><span class="katex"><span class="katex-mathml"><br />
<math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>71</mn></mrow><annotation encoding="application/x-tex">71</annotation></semantics></math></span></span></span>&nbsp;</li>
<li>Auto-Reload Register (ARR): <span class="katex"><span class="katex"><span class="katex-mathml"><br />
<math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>999</mn></mrow><annotation encoding="application/x-tex">999</annotation></semantics></math></span></span></span>&nbsp;</li>
</ul>
<p><strong>Steps</strong>:</p>
<ol>
<li>Calculate the timer clock:<span class="katex-display"><span class="katex"><span class="katex-mathml"></span></span></span>
<p><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>Timer Clock</mtext><mo>=</mo><mfrac><mrow><mn>72</mn><mtext> </mtext><mtext>MHz</mtext></mrow><mrow><mtext>Prescaler</mtext><mo>+</mo><mn>1</mn></mrow></mfrac><mo>=</mo><mfrac><mrow><mn>72</mn><mtext> </mtext><mtext>MHz</mtext></mrow><mrow><mn>71</mn><mo>+</mo><mn>1</mn></mrow></mfrac><mo>=</mo><mn>1</mn><mtext> </mtext><mtext>MHz</mtext></mrow><annotation encoding="application/x-tex">\text{Timer Clock} = \frac{72 \, \text{MHz}}{\text{Prescaler} + 1} = \frac{72 \, \text{MHz}}{71 + 1} = 1 \, \text{MHz}</annotation></semantics></math>&nbsp;</li>
<li>Calculate the PWM frequency:<span class="katex-display"><span class="katex"><span class="katex-mathml"></span></span></span>
<p><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mtext>PWM Frequency</mtext><mo>=</mo><mfrac><mtext>Timer Clock</mtext><mrow><mtext>ARR</mtext><mo>+</mo><mn>1</mn></mrow></mfrac><mo>=</mo><mfrac><mrow><mn>1</mn><mtext> </mtext><mtext>MHz</mtext></mrow><mrow><mn>999</mn><mo>+</mo><mn>1</mn></mrow></mfrac><mo>=</mo><mn>1</mn><mtext> </mtext><mtext>kHz</mtext></mrow><annotation encoding="application/x-tex">\text{PWM Frequency} = \frac{\text{Timer Clock}}{\text{ARR} + 1} = \frac{1 \, \text{MHz}}{999 + 1} = 1 \, \text{kHz}</annotation></semantics></math>&nbsp;</li>
</ol>
<p><strong>Result</strong>: The PWM frequency is <strong>1 kHz</strong>.</p>
<hr />
<h3>STM32 Configuration for PWM</h3>
<p>To set up PWM in STM32, follow these steps:</p>
<ol>
<li><strong>Initialize the Timer</strong>:
<ul>
<li>Set the prescaler and auto-reload values.</li>
<li>Configure the timer for PWM mode (e.g., using Timerx_CCMRx registers).</li>
</ul>
</li>
<li><strong>Set the Duty Cycle</strong>:
<ul>
<li>Configure the Capture/Compare Register (CCR) to control the duty cycle.<br />
For a 50% duty cycle, set <span class="katex"><span class="katex"><span class="katex-mathml"> <math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext>CCR</mtext><mo>=</mo><mfrac><mtext>ARR</mtext><mn>2</mn></mfrac></mrow><annotation encoding="application/x-tex">\text{CCR} = \frac{\text{ARR}}{2}</annotation></semantics></math></span></span></span>&nbsp;</p>
<p><span class="katex"><span class="katex-mathml"></span><br />
</span></li>
</ul>
</li>
<li><strong>Start PWM</strong>:
<ul>
<li>Enable the timer (e.g., using Timerx_CR1 register) and the output pin.</li>
</ul>
</li>
</ol>
<hr />
<h3>Applications of PWM in STM32</h3>
<ol>
<li><strong>LED Dimming</strong>: Control brightness by adjusting the duty cycle.</li>
<li><strong>Motor Speed Control</strong>: Vary the average voltage applied to the motor.</li>
<li><strong>Audio Generation</strong>: Create audio signals by varying PWM frequencies.</li>
<li><strong>Servo Control</strong>: Use PWM to control the position of servo motors</li>
</ol>
<p>&nbsp;</p>
<p>PWM is a versatile feature of STM32 timers, enabling precise control over frequency and duty cycle. By understanding parameters like the system clock, prescaler, and ARR, you can calculate and configure the desired PWM frequency for your application.</p>
<p>The post <a href="https://www.teachmemicro.com/stm32-pwm-calculator/">STM32 PWM Calculator</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-07-21 16:49:28 by W3 Total Cache
-->