<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://blog.implrust.com/feed_style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <tabi:metadata xmlns:tabi="https://github.com/welpo/tabi">
        <tabi:base_url>https:&#x2F;&#x2F;blog.implrust.com</tabi:base_url>
        <tabi:separator>
            •
        </tabi:separator>
        <tabi:about_feeds>This is a web feed, also known as an Atom feed. Subscribe by copying the URL from the address bar into your newsreader. Visit About Feeds to learn more and get started. It&#x27;s free.</tabi:about_feeds>
        <tabi:visit_the_site>Visit website</tabi:visit_the_site>
        <tabi:recent_posts>Recent posts</tabi:recent_posts>
        <tabi:last_updated_on>Updated on $DATE</tabi:last_updated_on>
        <tabi:default_theme></tabi:default_theme>
        <tabi:post_listing_date>date</tabi:post_listing_date>
        <tabi:current_section>debugging</tabi:current_section>
    </tabi:metadata><link rel="extra-stylesheet" href="https://blog.implrust.com/skins/lowcontrast_orange.css?h=43aaccb17d8ec616ace4" /><title>impl Blog for Rust - debugging</title>
        <subtitle>impl Rust Blog Posts</subtitle>
    <link href="https://blog.implrust.com/tags/debugging/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://blog.implrust.com/tags/debugging/" rel="alternate" type="text/html"/>
    <generator uri="https://www.getzola.org/">Zola</generator><updated>2026-01-28T00:00:00+00:00</updated><id>https://blog.implrust.com/tags/debugging/atom.xml</id><entry xml:lang="en">
        <title>Analyzing UART Signals in Embedded Rust Using a Cheap USB Logic Analyzer</title>
        <published>2026-01-28T00:00:00+00:00</published>
        <updated>2026-01-28T00:00:00+00:00</updated>
        <author>
            <name>implFerris</name>
        </author>
        <link rel="alternate" href="https://blog.implrust.com/posts/2026/01/analyze-uart-embedded-rust-with-usb-logic-analyzer/" type="text/html"/>
        <id>https://blog.implrust.com/posts/2026/01/analyze-uart-embedded-rust-with-usb-logic-analyzer/</id>
        
            <content type="html">&lt;p&gt;In my &lt;a href=&quot;https:&#x2F;&#x2F;blog.implrust.com&#x2F;posts&#x2F;2026&#x2F;01&#x2F;using-logic-analyzer-embedded-rust-pico-esp32&#x2F;&quot;&gt;previous blog post&lt;&#x2F;a&gt;, I introduced the USB logic analyzer, showed how to set up the software, and used a simple GPIO toggle to get familiar with how a logic analyzer works. In this post, we look at UART and see how serial data appears on the wire by analyzing the transmit (TX) signal and understanding how bytes are sent.&lt;&#x2F;p&gt;
&lt;p&gt;I initially planned to explain I2C right after the introduction, but I felt that UART is much simpler to start with and provides a gentler introduction to using protocol decoders in PulseView.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-uart&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#what-is-uart&quot; aria-label=&quot;Anchor link for: what-is-uart&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
What is UART?&lt;&#x2F;h2&gt;
&lt;p&gt;You might already be familiar with UART. Still, let me give a short introduction.&lt;&#x2F;p&gt;
&lt;p&gt;UART stands for Universal Asynchronous Receiver-Transmitter. It is a simple serial communication method used to send data between two devices. Data is sent one bit at a time, rather than in parallel.&lt;&#x2F;p&gt;
&lt;p&gt;UART typically uses two signal lines: one for transmitting data (TX) and one for receiving data (RX). The TX pin of one device is connected to the RX pin of the other, so data sent on TX is received on RX.&lt;&#x2F;p&gt;
&lt;p&gt;Unlike some other protocols, UART does not use a clock signal. So a natural question is how the receiver knows when data starts, when it ends, and how to interpret the bits correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Let us look at a simple UART signal to understand this.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-data-transmission.png&quot;  alt=&quot;uart data transmission&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;We can assign LOW state to 0 and HIGH to 1, but this alone is not enough. For example, suppose we want to transmit the value 0x52 (binary 0101_0010). If two or more bits in a row have the same value, such as two consecutive zeros, how does the receiver know whether it is seeing one long zero or multiple zeros?&lt;&#x2F;p&gt;
&lt;p&gt;This is where three important UART things come into play: the data length, the start and stop bits, and the transmission speed (baud rate). These three define how many bits make up a byte, and how the beginning and end of a byte are identified, how fast the data is sent.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;baud-rate-transmission-speed&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#baud-rate-transmission-speed&quot; aria-label=&quot;Anchor link for: baud-rate-transmission-speed&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Baud Rate (Transmission Speed)&lt;&#x2F;h3&gt;
&lt;p&gt;The baud rate defines how fast bits are transmitted on the wire. It specifies how many bits are sent per second. For example, a baud rate of 115200 means that 115200 bits are transmitted every second.&lt;&#x2F;p&gt;
&lt;p&gt;Both the transmitter and receiver must use the same baud rate. If the baud rate does not match, the receiver will sample the signal at the wrong times and decode incorrect data.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;data-length&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#data-length&quot; aria-label=&quot;Anchor link for: data-length&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Data Length&lt;&#x2F;h3&gt;
&lt;p&gt;The data length specifies how many data bits are sent for each character. The most common configuration is 8 data bits, but other values like 5 to 9 bits are also possible.&lt;&#x2F;p&gt;
&lt;p&gt;If the data length is set to 8 bits, then exactly 8 data bits are transmitted for each byte, one after another, starting with the least significant bit.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;start-and-stop-bits&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#start-and-stop-bits&quot; aria-label=&quot;Anchor link for: start-and-stop-bits&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Start and Stop Bits&lt;&#x2F;h3&gt;
&lt;p&gt;When the UART line is idle, it stays in the HIGH state. A transmission always begins with a start bit, which is a transition from HIGH to LOW.  This LOW level tells the receiver that a new byte is starting. Once the receiver detects the start bit, it uses the baud rate to time when to read the following data bits.&lt;&#x2F;p&gt;
&lt;p&gt;After all data bits are transmitted, the sender adds one or more stop bits. A stop bit is simply the line returning to the HIGH state for a fixed duration.&lt;&#x2F;p&gt;
&lt;p&gt;The stop bit marks the end of the byte and gives the receiver time to finish processing the current byte before the next one begins.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#example&quot; aria-label=&quot;Anchor link for: example&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Example&lt;&#x2F;h3&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-data-transmission-with-details.png&quot;  alt=&quot;uart data transmission with details&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;The above diagram shows the transmission of a single UART data byte. Before any data is sent, the signal stays in the idle state, which is HIGH.&lt;&#x2F;p&gt;
&lt;p&gt;The transmission begins with the start bit. The start bit is represented by pulling the signal LOW for exactly one bit duration. This transition from HIGH to LOW tells the receiver that a new byte is about to start.&lt;&#x2F;p&gt;
&lt;p&gt;Immediately after the start bit, the actual data bits are transmitted. In this example, the byte being sent is 0x52, which in binary is 0101_0010. UART sends data least significant bit first, so the first data bit sent is 0.&lt;&#x2F;p&gt;
&lt;p&gt;Because the start bit is LOW and the first data bit is also 0, the signal stays LOW for two consecutive bit periods. From the waveform alone, these two consecutive LOW levels appear as one continuous LOW signal. The receiver does not get confused because it does not rely on signal edges to count bits. Instead, it relies on timing.&lt;&#x2F;p&gt;
&lt;p&gt;This is where the baud rate comes in. The baud rate defines how long one bit lasts. For example, at a baud rate of 115200, each bit lasts for about 8.68 microseconds. The receiver measures time from the start bit and samples the signal at fixed intervals, once per bit period. By sampling at these precise times, it knows when one bit ends and the next bit begins, even if the signal level does not change.&lt;&#x2F;p&gt;
&lt;p&gt;After all data bits are transmitted, the signal returns to HIGH for the stop bit. The stop bit marks the end of the byte and brings the line back to the idle state. If another byte is sent, the process repeats with another start bit.&lt;&#x2F;p&gt;
&lt;p&gt;As long as both sides agree on the baud rate and data format, the receiver can correctly interpret a continuous stream of HIGH and LOW levels as individual bits and bytes.&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition tip&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-tip&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;TIP&lt;&#x2F;strong&gt;
        &lt;p&gt;I intentionally avoided many details of UART in this post. I only covered what is necessary for our purpose here and skipped other topics such as parity bits and other. If you want to go deeper, I recommend reading more about UART separately.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;hardware-setup&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#hardware-setup&quot; aria-label=&quot;Anchor link for: hardware-setup&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Hardware Setup&lt;&#x2F;h2&gt;
&lt;p&gt;For this post, I am focusing only on the transmit (TX) pin. The receive (RX) pin works in the same way, just in the opposite direction.&lt;&#x2F;p&gt;
&lt;p&gt;Once again, I am using a Raspberry Pi Pico. I will use one of the UART TX pins available on the Pico. In this example, I am using GPIO16 as the UART TX pin. You are free to use a different UART TX pin if you prefer, but you will need to adjust the code accordingly.&lt;&#x2F;p&gt;
&lt;p&gt;Connect CH1 of the logic analyzer to GPIO16 on the Pico. Also connect the logic analyzer ground to any ground pin on the Pico.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Logic Analyzer&lt;&#x2F;th&gt;&lt;th&gt;Raspberry Pi Pico&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;GND&lt;&#x2F;td&gt;&lt;td&gt;GND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;CH1&lt;&#x2F;td&gt;&lt;td&gt;GPIO16&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;code-snippet&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#code-snippet&quot; aria-label=&quot;Anchor link for: code-snippet&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Code Snippet&lt;&#x2F;h2&gt;
&lt;p&gt;Flash the program onto the Pico, then power up the board and connect the USB logic analyzer to the computer.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;embassy_executor&lt;&#x2F;span&gt;::&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;main&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;async &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;_spawner&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; Spawner&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; p &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;embassy_rp&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;init&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-rust&quot;&gt;Default&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;default&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; uart_config &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;UartConfig&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;default&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-comment z-line z-double-slash z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-rust&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt; This is default baud rate in the embassy-rp, i just want to explicitly show 
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    uart_config&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;baudrate &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;115200&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;  
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; uart_tx &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;UartTx&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;new_blocking&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;p&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-rust&quot;&gt;UART0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; p&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-rust&quot;&gt;PIN_16&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; uart_config&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-rust&quot;&gt;loop&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        uart_tx
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;            &lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;blocking_write&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Rust&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;as_bytes&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;            &lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;expect&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;unable to write into uart&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Timer&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;after_secs&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;await&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;number-of-samples-and-sample-rate&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#number-of-samples-and-sample-rate&quot; aria-label=&quot;Anchor link for: number-of-samples-and-sample-rate&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Number of Samples and Sample Rate&lt;&#x2F;h2&gt;
&lt;p&gt;In our example, the UART baud rate is 115200. To capture the signal reliably, we use a sample rate of 1 MHz, which is comfortably higher than the baud rate and works well with PulseView.&lt;&#x2F;p&gt;
&lt;p&gt;The program sends the string “Rust” once every second and then stays idle in between. Because of this, the capture window must be long enough to include at least one transmission.&lt;&#x2F;p&gt;
&lt;p&gt;Using 5 million samples at a 1 MHz sample rate gives a capture duration of about 5 seconds. This ensures that several UART transmissions are captured without having to worry about timing the capture manually.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-number-of-samples-sample-rate.png&quot;  alt=&quot;sample rate and number of samples&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;h2 id=&quot;start-the-capture&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#start-the-capture&quot; aria-label=&quot;Anchor link for: start-the-capture&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Start the Capture&lt;&#x2F;h2&gt;
&lt;p&gt;Since the program transmits the text “Rust” once every second, the capture contains multiple UART transmissions spread across the entire capture window. Because we are viewing several seconds of data at once, the waveform is zoomed out by default.&lt;&#x2F;p&gt;
&lt;p&gt;At first glance, it might look like nothing happened. The signal appears mostly flat, with a few thin vertical-looking shapes. These vertical shapes are not single lines. Each one represents a short burst of UART activity where the “Rust” string was transmitted.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-logic-analyzer-multiple-samples.png&quot;  alt=&quot;uart sample with logic analyzer&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;To see what is actually happening, zoom in horizontally on one of these regions (you can use the mouse scroll wheel while the cursor is over the signal). Once you zoom in far enough , the individual signal transitions become visible. At this level, you can see the structure of each UART transmission, but not the meaning of individual bits. To make sense of the data, we will use the protocol decoder feature.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;protocol-decoder&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#protocol-decoder&quot; aria-label=&quot;Anchor link for: protocol-decoder&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Protocol Decoder&lt;&#x2F;h2&gt;
&lt;p&gt;Looking at the raw UART signal helps confirm that data is being transmitted, but it does not tell us what the data actually is.&lt;&#x2F;p&gt;
&lt;p&gt;PulseView provides protocol decoders for many common digital protocols such as UART, I2C, and SPI. These decoders interpret raw signals and display the data in a readable form.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;logic-analyzer-protocl-decoder.png&quot;  alt=&quot;pulseview protocol decoder&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;To add a protocol decoder, click the small decoder icon next to the “sample rate” selection, as highlighted in the image above. This opens the Decoder selector.  In the search box, type &lt;code&gt;UART&lt;&#x2F;code&gt; and double-click the UART decoder. This adds a new UART decoder row to the main window.&lt;&#x2F;p&gt;
&lt;p&gt;After adding it, you will see a message saying that no channels are assigned to the decoder. At this point, PulseView knows which protocol to use, but it does not yet know which signal line to decode.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-pulseview-protocol-decoder.png&quot;  alt=&quot;pulseview UART decoder&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;Click on the UART label on the left side to open the decoder settings. Here, we need to configure the decoder to match our UART setup. Set the baud rate to 115200. The default values for data bits, parity, and stop bits are fine for this example.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-pulseview-protocol-decoder-options.png&quot;  alt=&quot;pulseview UART decoder&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;By default, the decoded data format is shown in hexadecimal. Since we are transmitting ASCII text, change the data format to ASCII.&lt;&#x2F;p&gt;
&lt;p&gt;Finally, assign the signal channel to the decoder. We have connected the UART TX pin to CH1, which corresponds to D0 in PulseView. Select D0 from the dropdown next to the TX option.&lt;&#x2F;p&gt;
&lt;p&gt;Once this is done, PulseView will decode the captured UART signal and display the transmitted data.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;decoded-data&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#decoded-data&quot; aria-label=&quot;Anchor link for: decoded-data&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Decoded Data&lt;&#x2F;h2&gt;
&lt;p&gt;PulseView decodes the captured UART signal and displays the data in a readable form. Along with the decoded characters (in ASCII, as we configured), it also shows the individual data bits as 0 and 1.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;uart-logic-analyzer-decoded-data.png&quot;  alt=&quot;pulseview UART decoder&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;PulseView also highlights the start bit with an “S” label (shown in yellow) and the stop bit with a “T” label.&lt;&#x2F;p&gt;
</content>
        <summary type="html">In this post, we analyze UART signals from an embedded Rust project using a cheap USB logic analyzer and PulseView. We capture UART data, look at the raw signal on the wire, and use protocol decoding to understand how bytes are transmitted.</summary>
        </entry><entry xml:lang="en">
        <title>How to Use a Logic Analyzer in Embedded Rust Projects</title>
        <published>2026-01-26T00:00:00+00:00</published>
        <updated>2026-01-26T00:00:00+00:00</updated>
        <author>
            <name>implFerris</name>
        </author>
        <link rel="alternate" href="https://blog.implrust.com/posts/2026/01/using-logic-analyzer-embedded-rust-pico-esp32/" type="text/html"/>
        <id>https://blog.implrust.com/posts/2026/01/using-logic-analyzer-embedded-rust-pico-esp32/</id>
        
            <content type="html">&lt;p&gt;I am a hobbyist embedded Rust developer. While researching and learning, I often came across people using oscilloscopes to analyze signals. I might have used one during my college lab days, but honestly, I do not remember much about it anymore. It has been a long time.&lt;&#x2F;p&gt;
&lt;p&gt;I was curious to try one again, but I did not want a large oscilloscope sitting on my desk. At least for now, it felt unnecessary. At some point, while looking for simpler ways to inspect digital signals, I came across USB logic analyzers. I do not remember exactly where I first saw one, but it immediately felt like a practical alternative. They are small, inexpensive, and much easier to keep around.&lt;&#x2F;p&gt;
&lt;p&gt;There are already plenty of tutorials and videos showing how to use logic analyzers, mostly with Arduino-based examples that you can follow step by step. I decided to write this post for my usual reason: the more I write and explain something, the more I understand it myself. Hopefully, you will find it useful too.&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition info&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-info&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;INFO&lt;&#x2F;strong&gt;
        &lt;p&gt;The Rust code is only a small part of this blog post. Most of the content focuses on understanding the logic analyzer, setting up the software, and learning how to capture and analyze digital signals.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;what-is-a-logic-analyzer&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#what-is-a-logic-analyzer&quot; aria-label=&quot;Anchor link for: what-is-a-logic-analyzer&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
What is a Logic Analyzer?&lt;&#x2F;h2&gt;
&lt;p&gt;A logic analyzer is a tool used to capture and inspect digital signals. It records whether a signal is in a logical HIGH or LOW state over time and how different signal lines, such as clock and data wires, relate to each other during communication.&lt;&#x2F;p&gt;
&lt;p&gt;For embedded development, this is especially useful when working with digital protocols such as I2C, SPI, or UART. Instead of relying on assumptions or print-based debugging, a logic analyzer lets you inspect the actual signal behavior on the wire.&lt;&#x2F;p&gt;
&lt;p&gt;Unlike an oscilloscope, which focuses on the exact voltage shape of a signal, a logic analyzer treats signals as digital values. It does not care about the precise voltage level or waveform details, only whether the signal is interpreted as a zero or a one. For most protocol-level debugging, this level of detail is sufficient and much easier to work with.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;meet-the-hardware-8-channel-usb-logic-analyzer&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#meet-the-hardware-8-channel-usb-logic-analyzer&quot; aria-label=&quot;Anchor link for: meet-the-hardware-8-channel-usb-logic-analyzer&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Meet the Hardware: 8-Channel USB Logic Analyzer&lt;&#x2F;h2&gt;
&lt;p&gt;The logic analyzer I am using is a small 8-channel USB logic analyzer with a maximum sampling frequency of 24 MHz. You should be able to find one on online marketplaces for under 400 INR (under $10).&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;8-channel-usb-logic-analyzer.png&quot;  alt=&quot;8 ch USB Logic Analyzer&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;As the name implies, the analyzer allows capturing up to eight digital signals at the same time, which makes it possible to observe how multiple related signals change together.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-a-logic-analyzer-captures-data&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#how-a-logic-analyzer-captures-data&quot; aria-label=&quot;Anchor link for: how-a-logic-analyzer-captures-data&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
How a Logic Analyzer Captures Data&lt;&#x2F;h2&gt;
&lt;p&gt;A logic analyzer repeatedly checks the state of each connected signal and records whether it is HIGH or LOW. These checks happen at regular intervals, based on the selected sampling rate(will see it later).&lt;&#x2F;p&gt;
&lt;p&gt;The logic analyzer itself does not understand protocols or signal meaning. It only records state changes. Interpreting those changes and decoding protocols is done later using software on the computer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;channels&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#channels&quot; aria-label=&quot;Anchor link for: channels&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Channels&lt;&#x2F;h2&gt;
&lt;p&gt;A logic analyzer has multiple input channels. Each channel is a separate input that can be connected to a signal wire or a microcontroller pin. When the analyzer captures data, it records the state of each channel independently.&lt;&#x2F;p&gt;
&lt;p&gt;When connecting the analyzer, each channel should be connected to one signal of interest, such as a data line or a clock line. The exact choice of signals depends on what you are trying to observe. For now, the important point is that each channel corresponds to one physical wire or pin.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;software-setup&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#software-setup&quot; aria-label=&quot;Anchor link for: software-setup&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Software Setup&lt;&#x2F;h2&gt;
&lt;p&gt;I am on Linux, so I will describe the setup steps for Linux here. If you are using a different operating system, you can follow similar steps using the appropriate tools and packages for your OS.&lt;&#x2F;p&gt;
&lt;p&gt;There are two commonly mentioned software options when working with USB logic analyzers. Which one makes sense depends on the hardware you are using.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;option-1-pulseview-sigrok-open-source&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#option-1-pulseview-sigrok-open-source&quot; aria-label=&quot;Anchor link for: option-1-pulseview-sigrok-open-source&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Option 1: PulseView (sigrok, Open Source)&lt;&#x2F;h3&gt;
&lt;p&gt;For inexpensive 8-channel USB logic analyzers like the one I am using, the most practical software is PulseView, which is part of the open-source sigrok project. PulseView supports many generic logic analyzers and provides the basic tools needed to view captured signals and decode common digital protocols.&lt;&#x2F;p&gt;
&lt;p&gt;On Debian or Ubuntu-based systems, you can install PulseView using the package manager:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;sudo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; apt install pulseview sigrok&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Official documentation for sigrok and PulseView is available here:
&lt;a href=&quot;https:&#x2F;&#x2F;sigrok.org&#x2F;wiki&#x2F;Main_Page&quot;&gt;https:&#x2F;&#x2F;sigrok.org&#x2F;wiki&#x2F;Main_Page&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You can also refer to the PulseView user manual for more details:
&lt;a href=&quot;https:&#x2F;&#x2F;sigrok.org&#x2F;doc&#x2F;pulseview&#x2F;unstable&#x2F;manual.html&quot;&gt;https:&#x2F;&#x2F;sigrok.org&#x2F;doc&#x2F;pulseview&#x2F;unstable&#x2F;manual.html&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I will be using PulseView throughout this blog post.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;option-2-saleae-logic-software-proprietary&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#option-2-saleae-logic-software-proprietary&quot; aria-label=&quot;Anchor link for: option-2-saleae-logic-software-proprietary&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Option 2: Saleae Logic Software (Proprietary)&lt;&#x2F;h3&gt;
&lt;p&gt;Saleae provides software specifically designed for their logic analyzers, though it may also work with some compatible devices.&lt;&#x2F;p&gt;
&lt;p&gt;You can download the Linux AppImage from the Saleae website:
&lt;a href=&quot;https:&#x2F;&#x2F;www.saleae.com&#x2F;downloads&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.saleae.com&#x2F;downloads&#x2F;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Make it executable and run:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;chmod&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; +x Logic-&lt;span class=&quot;z-keyword z-operator z-regexp z-quantifier z-shell&quot;&gt;*&lt;&#x2F;span&gt;.AppImage&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.&#x2F;Logic-*.AppImage&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;toggling-a-gpio-test-signal&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#toggling-a-gpio-test-signal&quot; aria-label=&quot;Anchor link for: toggling-a-gpio-test-signal&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Toggling a GPIO (Test Signal)&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s start by generating a very simple test signal by toggling a GPIO pin. This helps confirm that the logic analyzer, software, and wiring are all working correctly before moving on to more complex signals.&lt;&#x2F;p&gt;
&lt;p&gt;I will be using a Raspberry Pi Pico here, but any other board will work.&lt;&#x2F;p&gt;
&lt;p&gt;We will flash a small program that toggles a GPIO pin between high and low states with a delay of 500 milliseconds.&lt;&#x2F;p&gt;
&lt;p&gt;For the HAL, I will be using Embassy. You are free to use any other HAL, such as rp-hal. The choice of HAL does not matter here, as long as you can toggle a GPIO pin at a known interval and observe the change on the logic analyzer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;code-snippet&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#code-snippet&quot; aria-label=&quot;Anchor link for: code-snippet&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Code snippet&lt;&#x2F;h3&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; p &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;embassy_rp&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;init&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-type z-rust&quot;&gt;Default&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;default&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; pin &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Output&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;new&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;p&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-other z-rust&quot;&gt;PIN_15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Level&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;Low&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-keyword z-control z-rust&quot;&gt;loop&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    pin&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;set_high&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Timer&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;after_millis&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;await&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    pin&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;set_low&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Timer&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;after_millis&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;500&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;await&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;admonition tip&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-tip&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;TIP&lt;&#x2F;strong&gt;
        &lt;p&gt;If you are not familiar with creating a project or flashing embedded Rust code onto a board, you may want to go through the basics first. I recommend starting with the &lt;a href=&quot;https:&#x2F;&#x2F;pico.implrust.com&#x2F;&quot;&gt;Pico Pico book&lt;&#x2F;a&gt; or the &lt;a href=&quot;https:&#x2F;&#x2F;esp32.implrust.com&#x2F;&quot;&gt;impl Rust for ESP32&lt;&#x2F;a&gt; book.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;connecting-pico-with-logic-analyzer&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#connecting-pico-with-logic-analyzer&quot; aria-label=&quot;Anchor link for: connecting-pico-with-logic-analyzer&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Connecting Pico with Logic Analyzer&lt;&#x2F;h3&gt;
&lt;p&gt;First, connect the ground wire of the logic analyzer to one of the ground pins on the Raspberry Pi Pico. The logic analyzer and the Pico must share a common ground for the signals to be interpreted correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Next, connect one channel (lets say CH1) of the logic analyzer to GPIO15 on the Pico. For this test, I am using GPIO15, but you can use any other GPIO pin.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Logic Analyzer&lt;&#x2F;th&gt;&lt;th&gt;Raspberry Pi Pico&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;GND&lt;&#x2F;td&gt;&lt;td&gt;GND&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;CH1&lt;&#x2F;td&gt;&lt;td&gt;GPIO15&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Power the Pico, then connect the logic analyzer to the computer.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;opening-pulseview-and-detecting-the-logic-analyzer&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#opening-pulseview-and-detecting-the-logic-analyzer&quot; aria-label=&quot;Anchor link for: opening-pulseview-and-detecting-the-logic-analyzer&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Opening PulseView and Detecting the Logic Analyzer&lt;&#x2F;h2&gt;
&lt;p&gt;Now lets open PulseView and make sure the logic analyzer is detected correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Start PulseView after connecting the logic analyzer to your computer. When PulseView opens, it should automatically try to detect connected devices.  If the logic analyzer is detected, you should see it selected as the active device in the toolbar.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;pulseview-logic-analyzer-detected.png&quot;  alt=&quot;Pulseview detected the logic analyzer&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;If no device is selected, open the device selection menu and choose the generic logic analyzer entry, which usually appears as fx2lafw (generic driver). Once selected, PulseView should show the available channels for that device.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;configuring-sampling-rate-and-number-of-samples&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#configuring-sampling-rate-and-number-of-samples&quot; aria-label=&quot;Anchor link for: configuring-sampling-rate-and-number-of-samples&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Configuring Sampling Rate and Number of Samples&lt;&#x2F;h2&gt;
&lt;p&gt;Once the logic analyzer is detected in PulseView, the next step is to configure how data will be captured. Two important settings here are the “sample rate” and the “number of samples to capture”.&lt;&#x2F;p&gt;
&lt;p&gt;To understand these settings, it helps to know what a sample actually is.&lt;&#x2F;p&gt;
&lt;p&gt;A sample is a single recorded value of the signal. At that moment, the logic analyzer simply reads the wire and records whether the signal is HIGH or LOW. Each recorded HIGH or LOW value is one sample.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;number-of-samples-sampel-rate-logic-analyzer-pulseview.png&quot;  alt=&quot;Number of Samples - Sample Rate&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;h3 id=&quot;number-of-samples&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#number-of-samples&quot; aria-label=&quot;Anchor link for: number-of-samples&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Number of Samples&lt;&#x2F;h3&gt;
&lt;p&gt;The number of samples tells the logic analyzer how many samples to record in total before stopping.&lt;&#x2F;p&gt;
&lt;p&gt;For example, if you set this to 100k, the logic analyzer will record 100,000 values (each value being either HIGH or LOW) and then stop automatically. Increasing this value makes the recording last longer. Decreasing it makes the recording shorter.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sample-rate&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#sample-rate&quot; aria-label=&quot;Anchor link for: sample-rate&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Sample Rate&lt;&#x2F;h3&gt;
&lt;p&gt;The sample rate tells the logic analyzer how many samples to take every second.&lt;&#x2F;p&gt;
&lt;p&gt;For example, a sample rate of 20 kHz means the logic analyzer records 20,000 samples every second. That means it reads the signal 20,000 times per second and saves each result.&lt;&#x2F;p&gt;
&lt;p&gt;A higher sample rate means the signal is read and recorded more frequently. This is important when the signal changes quickly. A lower sample rate means the signal is read less often, which is usually fine for slow signals.&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition tip&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-tip&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;TIP&lt;&#x2F;strong&gt;
        &lt;p&gt;&lt;strong&gt;From the Manual:&lt;&#x2F;strong&gt; The sample rate you choose must at least be twice that of the highest frequency you want to capture - ideally 3 to 5 times as much so that you have some margin. That way, a jittering signal won’t ruin your measurements.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;how-they-work-together&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#how-they-work-together&quot; aria-label=&quot;Anchor link for: how-they-work-together&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
How They Work Together&lt;&#x2F;h3&gt;
&lt;p&gt;These two settings answer two different questions:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;“The sample rate” answers how fast samples are taken&lt;&#x2F;li&gt;
&lt;li&gt;“The number of samples” answers how many samples are taken&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Together, they decide how long the signal is recorded.&lt;&#x2F;p&gt;
&lt;p&gt;PulseView shows this relationship using the capture duration:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;capture&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; duration = number of samples &#x2F; sample rate&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Suppose you set the sample rate to 20 kHz and the number of samples to 100k. At a 20 kHz sample rate, the logic analyzer records 20,000 samples every second. With 100,000 samples in total, the recording will last for about 5 seconds before stopping.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;capture&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; duration = 100,000 &#x2F; 20,000 = 5 seconds&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We will use this setting only for our test. It is sufficient here because we are just toggling the GPIO every 500 milliseconds.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;starting-the-capture-and-verifying-the-signal&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#starting-the-capture-and-verifying-the-signal&quot; aria-label=&quot;Anchor link for: starting-the-capture-and-verifying-the-signal&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
Starting the Capture and Verifying the Signal&lt;&#x2F;h2&gt;
&lt;p&gt;With the logic analyzer connected and the capture settings configured, we can now start the capture.&lt;&#x2F;p&gt;
&lt;p&gt;In PulseView, click Run in the top bar (next to the Session label). The logic analyzer will begin recording samples and will automatically stop once it reaches the configured number of samples.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;img&#x2F;2026&#x2F;01&#x2F;logic-analyzer-signal-captured.png&quot;  alt=&quot;Logic Analyzer Signal Captured&quot; style=&quot;width:400px; height:auto; display:block; margin:auto;&quot;&#x2F;&gt;
&lt;p&gt;After the capture stops, you should see a waveform on the enabled channel. In our program, the GPIO state is toggled every 500 milliseconds. As shown in the capture, the signal stays HIGH for 500 ms, then LOW for 500 ms, repeating this pattern consistently.&lt;&#x2F;p&gt;
&lt;p&gt;Since the total capture duration is 5 seconds, this results in 5 HIGH periods and 5 LOW periods across the entire waveform.&lt;&#x2F;p&gt;
&lt;p&gt;Even though the waveform shows only a few visible transitions, the logic analyzer actually recorded all 100,000 samples. Each HIGH or LOW section in the waveform represents many individual samples taken during that time. PulseView automatically zooms out to show the overall shape of the signal rather than displaying every sample at once.&lt;&#x2F;p&gt;
&lt;p&gt;If you zoom in horizontally, you will see that each flat HIGH or LOW region is made up of many samples. This confirms that the GPIO toggling, sampling configuration, and capture duration are all working together as expected.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;&lt;a class=&quot;header-anchor no-hover-padding&quot; href=&quot;#what-s-next&quot; aria-label=&quot;Anchor link for: what-s-next&quot;&gt;&lt;span class=&quot;link-icon&quot; aria-hidden=&quot;true&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;a&gt;
What’s Next&lt;&#x2F;h2&gt;
&lt;p&gt;In this post, we focused on getting familiar with the logic analyzer and basic signal capture. I am planning to write a follow-up post focused on analyzing I2C signals, and later cover other protocols as well.&lt;&#x2F;p&gt;
</content>
        <summary type="html">In this post, we take a practical look at using a logic analyzer when working on embedded Rust projects. We cover what a logic analyzer does, how to interpret captured signals, and how it can be used to debug common protocols like I2C, SPI, and UART.</summary>
        </entry>
</feed>
