Files
ESP-Nodes/ESP-IDF_Robot/tutorial/docs/build/html/overview.html
2025-07-05 23:34:06 -04:00

304 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en" data-content_root="./">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
<title>HOW DOES IT WORK? &#8212; Byte Rider 06-2025 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css?v=5ecbeea2" />
<link rel="stylesheet" type="text/css" href="_static/basic.css?v=b08954a9" />
<link rel="stylesheet" type="text/css" href="_static/alabaster.css?v=27fed22d" />
<script src="_static/documentation_options.js?v=e6ef2064"></script>
<script src="_static/doctools.js?v=9bcbadda"></script>
<script src="_static/sphinx_highlight.js?v=dc90522c"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="DATA STRUCT" href="data.html" />
<link rel="prev" title="OVERVIEW" href="intro.html" />
<link rel="stylesheet" href="_static/custom.css" type="text/css" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="how-does-it-work">
<h1>HOW DOES IT WORK?<a class="headerlink" href="#how-does-it-work" title="Link to this heading"></a></h1>
<p>The BitByteRider RC car is powered by ESP32-C3 Breadboard &amp; Power adapter developmemt board.
The Schematic and KiCAd PCB board are available on <a class="reference external" href="https://github.com/alexandrebobkov/ESP32-C3_Breadboard-Adapter">GitHub</a>: <a class="reference external" href="https://github.com/alexandrebobkov/ESP32-C3_Breadboard-Adapter">https://github.com/alexandrebobkov/ESP32-C3_Breadboard-Adapter</a></p>
<section id="reserved-pins-gpios">
<h2>Reserved Pins &amp; GPIOs<a class="headerlink" href="#reserved-pins-gpios" title="Link to this heading"></a></h2>
<p>The following table summarizes GPIOs and pins reserved for operations purposes.</p>
<p>The GPIO numbers correspond to those on the ESP32-C3 WROOM microcontroller. The Pin number corresponds to the pin on the Breadboard and Power adapter development board.</p>
<section id="x-and-y-axis">
<h3>x- and y- axis<a class="headerlink" href="#x-and-y-axis" title="Link to this heading"></a></h3>
<p>The <strong>GPIO0</strong> and <strong>GPIO1</strong> assigned to measuring the voltage of x- and y- axis of the Joystick. Lastly, there is a group of GPIO pairs responsible for PWM for DC motors.</p>
</section>
<section id="direction-and-speed">
<h3>Direction and Speed<a class="headerlink" href="#direction-and-speed" title="Link to this heading"></a></h3>
<p>The pairs of DC motors on the left side are wired to the dedicated PWM channels. This means that <em>ESP32-C3 Breadboard DevBoard</em> can control rotation speed and direction of DC motors in pairs only (i.e. left and right side).
Consequently, only four PWM channels are sufficient for controlling the direction of the RC car.
Based on this constraint, the RC car can only move front, back, and turn/rotate left and right. Any other movements are not possible (i.e. diagonal or sideways).</p>
<div class="admonition-what-is-pwm admonition">
<p class="admonition-title">What is PWM?</p>
<p><strong>PWM</strong> stands for Pulse Width Modulation. It is a technique used to simulate analog voltage levels using discrete digital signals. It works by
rapidly switching a digital GPIO pin between HIGH (on) and LOW (off) states at a fixed frequency (often, at base frequency of 5 kHz).
The duty cycle—the percentage of time the signal is HIGH in one cycle determines the effective voltage delivered to a device.</p>
<p>A higher duty cycle increases the motor speed, and a lower duty cycle decreases the motor speed. This allows for fine-grained speed control
without needing analog voltage regulators.</p>
</div>
<p>A pair of PWM channels are used per DC motor for defining their rotation speed and direction on each side.
In particular, <strong>GPIO6</strong> and <strong>GPIO5</strong> provide PWM to the left- and right- side DC motors to rotate in a <strong>clockwise</strong> direction.
Similarly, <strong>GPIO4</strong> and <strong>GPIO7</strong> provide PWM to the left- and right- side DC motors to rotate in a <strong>counter-clockwise</strong> direction.
Changing PWM on each channel determines the speed and direction of the RC car.</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>GPIO Num.</p></th>
<th class="head"><p>State</p></th>
<th class="head"><p>Function</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>GPIO6
GPIO4</p></td>
<td><p>PWM</p></td>
<td><p>Forward</p></td>
</tr>
</tbody>
</table>
<p>The following images illustrate various PWM duty cycles registered by oscilloscope (duty cycles 0%, 48% and 91%, resp.).</p>
<figure class="align-default" id="id1">
<img alt="_images/ESP-IDF_Robot_PWM_Duty-0.bmp" src="_images/ESP-IDF_Robot_PWM_Duty-0.bmp" />
<figcaption>
<p><span class="caption-text">DC Motor PWM duty cycle 0%</span><a class="headerlink" href="#id1" title="Link to this image"></a></p>
</figcaption>
</figure>
<figure class="align-default" id="id2">
<img alt="_images/ESP-IDF_Robot_PWM_Duty-50.bmp" src="_images/ESP-IDF_Robot_PWM_Duty-50.bmp" />
<figcaption>
<p><span class="caption-text">DC Motor PWM duty cycle 47.6%</span><a class="headerlink" href="#id2" title="Link to this image"></a></p>
</figcaption>
</figure>
<figure class="align-default" id="id3">
<img alt="_images/ESP-IDF_Robot_PWM_Duty-95.bmp" src="_images/ESP-IDF_Robot_PWM_Duty-95.bmp" />
<figcaption>
<p><span class="caption-text">DC Motor PWM duty cycle 90.8%</span><a class="headerlink" href="#id3" title="Link to this image"></a></p>
</figcaption>
</figure>
<br/><br/><br/><br/><table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>GPIO</p></th>
<th class="head"><p>Pin</p></th>
<th class="head"><p>Function</p></th>
<th class="head"><p>Notes</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p>0</p></td>
<td><p>16</p></td>
<td><p>Joystick x-axis</p></td>
<td><p>ADC1_CH0</p></td>
</tr>
<tr class="row-odd"><td><p>1</p></td>
<td><p>15</p></td>
<td><p>Joystick y-axis</p></td>
<td><p>ADC1_CH1</p></td>
</tr>
<tr class="row-even"><td><p>8</p></td>
<td><p>5</p></td>
<td><p>Joystick push button</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p>6</p></td>
<td><p>4</p></td>
<td><p>PWM for clockwise rotation of left-side motors</p></td>
<td><p>LEDC_CHANNEL_1</p></td>
</tr>
<tr class="row-even"><td><p>5</p></td>
<td><p>3</p></td>
<td><p>PWM for clockwise rotation of right-side motors</p></td>
<td><p>LEDC_CHANNEL_0</p></td>
</tr>
<tr class="row-odd"><td><p>4</p></td>
<td><p>2</p></td>
<td><p>PWM for counter-clockwise rotation of right-side motors</p></td>
<td><p>LEDC_CHANNEL_2</p></td>
</tr>
<tr class="row-even"><td><p>7</p></td>
<td><p>6</p></td>
<td><p>PWM for counter-clockwise rotation of left-side motors</p></td>
<td><p>LEDC_CHANNEL_3</p></td>
</tr>
</tbody>
</table>
</section>
</section>
<section id="fusion-of-software-with-hardware">
<h2>Fusion of Software with Hardware<a class="headerlink" href="#fusion-of-software-with-hardware" title="Link to this heading"></a></h2>
<p>The <em>struct</em> for storing motors PWM values.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="k">struct</span><span class="w"> </span><span class="nc">motors_rpm</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">motor1_rpm_pwm</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">motor2_rpm_pwm</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">motor3_rpm_pwm</span><span class="p">;</span>
<span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">motor4_rpm_pwm</span><span class="p">;</span>
<span class="p">};</span>
</pre></div>
</div>
<p>The function for updating motors PWM values.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="c1">// Function to send data to the receiver</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">sendData</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">sensors_data_t</span><span class="w"> </span><span class="n">buffer</span><span class="p">;</span><span class="w"> </span><span class="c1">// Declare data struct</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">crc</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">x_axis</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">y_axis</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">nav_bttn</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">motor1_rpm_pwm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">motor2_rpm_pwm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">motor3_rpm_pwm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="n">buffer</span><span class="p">.</span><span class="n">motor4_rpm_pwm</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<span class="w"> </span><span class="c1">// Display brief summary of data being sent.</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Joystick (x,y) position ( 0x%04X, 0x%04X )&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">x_axis</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">y_axis</span><span class="p">);</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;pwm 1, pwm 2 [ 0x%04X, 0x%04X ]&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">pwm</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">pwm</span><span class="p">);</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;pwm 3, pwm 4 [ 0x%04X, 0x%04X ]&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">pwm</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="p">)</span><span class="n">buffer</span><span class="p">.</span><span class="n">pwm</span><span class="p">);</span>
<span class="w"> </span><span class="c1">// Call ESP-NOW function to send data (MAC address of receiver, pointer to the memory holding data &amp; data length)</span>
<span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">esp_now_send</span><span class="p">(</span><span class="n">receiver_mac</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">buffer</span><span class="p">,</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="n">buffer</span><span class="p">));</span>
<span class="w"> </span><span class="c1">// If status is NOT OK, display error message and error code (in hexadecimal).</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">result</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">ESP_LOGE</span><span class="p">(</span><span class="s">&quot;ESP-NOW&quot;</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Error sending data! Error code: 0x%04X&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">result</span><span class="p">);</span>
<span class="w"> </span><span class="n">deletePeer</span><span class="p">();</span>
<span class="w"> </span><span class="p">}</span>
<span class="w"> </span><span class="k">else</span>
<span class="w"> </span><span class="n">ESP_LOGW</span><span class="p">(</span><span class="s">&quot;ESP-NOW&quot;</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Data was sent.&quot;</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The onDataReceived() and onDataSent() are two call-bacl functions that get evoked on each corresponding event.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="c1">// Call-back for the event when data is being received</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">onDataReceived</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">mac_addr</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">data</span><span class="p">,</span><span class="w"> </span><span class="kt">uint8_t</span><span class="w"> </span><span class="n">data_len</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">buf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">sensors_data_t</span><span class="o">*</span><span class="p">)</span><span class="n">data</span><span class="p">;</span><span class="w"> </span><span class="c1">// Allocate memory for buffer to store data being received</span>
<span class="w"> </span><span class="n">ESP_LOGW</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Data was received&quot;</span><span class="p">);</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;x-axis: 0x%04x&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="o">-&gt;</span><span class="n">x_axis</span><span class="p">);</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;x-axis: 0x%04x&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="o">-&gt;</span><span class="n">y_axis</span><span class="p">);</span>
<span class="w"> </span><span class="n">ESP_LOGI</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;PWM 1: 0x%04x&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">buf</span><span class="o">-&gt;</span><span class="n">motor1_rpm_pwm</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// Call-back for the event when data is being sent</span>
<span class="kt">void</span><span class="w"> </span><span class="nf">onDataSent</span><span class="w"> </span><span class="p">(</span><span class="kt">uint8_t</span><span class="w"> </span><span class="o">*</span><span class="n">mac_addr</span><span class="p">,</span><span class="w"> </span><span class="n">esp_now_send_status_t</span><span class="w"> </span><span class="n">status</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="n">ESP_LOGW</span><span class="p">(</span><span class="n">TAG</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Packet send status: 0x%04X&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">status</span><span class="p">);</span>
<span class="p">}</span>
</pre></div>
</div>
<p>The rc_send_data_task() function runs every 0.1 second to transmit the data to the receiver.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></span><span class="c1">// Continous, periodic task that sends data.</span>
<span class="k">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">rc_send_data_task</span><span class="w"> </span><span class="p">(</span><span class="kt">void</span><span class="w"> </span><span class="o">*</span><span class="n">arg</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="nb">true</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">esp_now_is_peer_exist</span><span class="p">(</span><span class="n">receiver_mac</span><span class="p">))</span>
<span class="w"> </span><span class="n">sendData</span><span class="p">();</span>
<span class="w"> </span><span class="n">vTaskDelay</span><span class="w"> </span><span class="p">(</span><span class="mi">100</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">portTICK_PERIOD_MS</span><span class="p">);</span>
<span class="w"> </span><span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
</section>
<section id="schematic">
<h2>Schematic<a class="headerlink" href="#schematic" title="Link to this heading"></a></h2>
<img alt="_images/ESP-IDF_Robot_schematic.png" src="_images/ESP-IDF_Robot_schematic.png" />
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="Main">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="index.html">Byte Rider</a></h1>
<search id="searchbox" style="display: none" role="search">
<div class="searchformwrapper">
<form class="search" action="search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" placeholder="Search"/>
<input type="submit" value="Go" />
</form>
</div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script><h3>Navigation</h3>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="intro.html">OVERVIEW</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">HOW DOES IT WORK?</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#reserved-pins-gpios">Reserved Pins &amp; GPIOs</a></li>
<li class="toctree-l2"><a class="reference internal" href="#fusion-of-software-with-hardware">Fusion of Software with Hardware</a></li>
<li class="toctree-l2"><a class="reference internal" href="#schematic">Schematic</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="data.html">DATA STRUCT</a></li>
<li class="toctree-l1"><a class="reference internal" href="transmitter.html">TRANSMITTER</a></li>
<li class="toctree-l1"><a class="reference internal" href="receiver.html">RECEIVER</a></li>
<li class="toctree-l1"><a class="reference internal" href="progress.html">WORK-IN-PROGRESS WALK THROUGH</a></li>
<li class="toctree-l1"><a class="reference internal" href="references.html">REFERENCES</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="index.html">Documentation overview</a><ul>
<li>Previous: <a href="intro.html" title="previous chapter">OVERVIEW</a></li>
<li>Next: <a href="data.html" title="next chapter">DATA STRUCT</a></li>
</ul></li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&#169;2025, Alexander B.
|
Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.2.3</a>
&amp; <a href="https://alabaster.readthedocs.io">Alabaster 1.0.0</a>
|
<a href="_sources/overview.rst.txt"
rel="nofollow">Page source</a>
</div>
</body>
</html>