Files
ESP-Nodes/ESP-IDF_Robot/tutorial/docs/build/html/overview.html
2025-07-21 03:14:40 -04:00

406 lines
30 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>2. 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="3. DATA STRUCTS" href="data.html" />
<link rel="prev" title="1. 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><span class="section-number">2. </span>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 bitBoard. The Schematic and KiCAd PCB board files 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>
<p>The bitByteRider RC car operates using two main units: the <em>transmitter</em>, which reads and sends the joysticks X and Y values, and
the <em>receiver</em>, which interprets these values and converts them into PWM signals to control the DC motors. Both units communicate
via <strong>ESP-NOW</strong>, a low-latency, connectionless wireless protocol that requires no Wi-Fi network or pairing.</p>
<p>In addition to enabling real-time control, using ESP-NOW introduces key networking concepts such as <strong>data encapsulation</strong> and
structured communication. By using data structures to group control variables, you gain hands-on experience with how information
is packaged and transmitted, laying the groundwork for understanding the fundamentals of network communication in embedded systems.</p>
<p>The joystick used in the bitByteRider RC car remote unit outputs analog voltages ranging from 0V to 3.3V on both the x- and y-axes,
depending on the position of the joystick. These voltage levels are read by the ESP32-C3s ADC (Analog-to-Digital Converter) inputs.</p>
<p>When the joystick is in its neutral (centred) position, the ADC inputs on the ESP32-C3 receive approximately 1.65V on both axes.
This midpoint voltage is interpreted and interpolated into a PWM (Pulse Width Modulation) value of 0, indicating no movement or
motor activity.</p>
<p>As the joystick is pushed to its maximum positions along the x- and y-axis, the voltage increases up to 3.3V. This maximum voltage
is interpolated to a PWM value of 1024, which corresponds to a 100% duty cycle on the receiver side, resulting in full-speed
operation of the DC motors.</p>
<p>To transmit control data, the X and Y axis values are encapsulated in a C struct, along with the receivers <strong>MAC</strong> address, and sent
wirelessly using ESP-NOW. This protocol enables low-latency, connectionless communication between the transmitter and receiver
without requiring a Wi-Fi network or pairing.</p>
<p>Upon reception, the RC cars receiver decapsulates the data, extracts the joystick values, and interpolates them into PWM
signals. These signals are then used to control the rotation speeds of the DC motors, enabling smooth and responsive remote control.</p>
<p>This process not only facilitates real-time control but also introduces you to key networking concepts such as data
encapsulation, data structs, and the fundamentals of wireless data transmission in embedded systems.</p>
<div class="admonition-what-is-encapsulation admonition">
<p class="admonition-title">What is encapsulation?</p>
<p>Encapsulation refers to the process of organizing and packaging data into a structured format before it is transmitted between
devices. This is a fundamental concept in networking and communication protocols, including those used in IoT systems.</p>
</div>
<section id="reserved-pins-gpios">
<h2><span class="section-number">2.1. </span>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="reading-the-joystick-x-and-y-axis">
<h3><span class="section-number">2.1.1. </span>Reading the Joystick x- and y- axis<a class="headerlink" href="#reading-the-joystick-x-and-y-axis" title="Link to this heading"></a></h3>
<p>To determine the position of the Joystick, the BitRider RC car uses ADC to measure voltage on two GPIOs connected to the joystick
x- and y- axis potentionometers (<strong>GPIO0</strong> and <strong>GPIO1</strong>).</p>
</section>
<section id="controlling-the-direction-and-speed">
<h3><span class="section-number">2.1.2. </span>Controlling the Direction and Speed<a class="headerlink" href="#controlling-the-direction-and-speed" title="Link to this heading"></a></h3>
<p>To set any desired speed of BiteRider RC car, the <em>ESP32-C3 Breadboard Adapter DevBoard</em> uses PWM to control the rotation speed
of DR motors. Similarly, to set the direction of the RC car, the rotation speed of corresponding DC motors is changed as required.</p>
<p>Due to the design and limited number of available GPIOs, the <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, this means that the four PWM channels used for controlling the
direction of the RC car.</p>
<p>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>
<table class="docutils align-default">
<tbody>
<tr class="row-odd"><td><p>PWM of DC Motors</p></td>
<td><p>Direction</p></td>
</tr>
<tr class="row-even"><td><p>PWM(left) = PWM(right)</p></td>
<td><p>Straight</p></td>
</tr>
<tr class="row-odd"><td><p>PWM(left) &gt; PWM(right)</p></td>
<td><p>Left</p></td>
</tr>
<tr class="row-even"><td><p>PWM(left) &lt; PWM(right)</p></td>
<td><p>Right</p></td>
</tr>
</tbody>
</table>
<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.
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>
<p>The table below summarizes the GPIO pins used for PWM to control the direction of the DC motors in the remote-controlled car.</p>
<table class="docutils align-default">
<thead>
<tr class="row-odd"><th class="head"><p>GPIOs</p></th>
<th class="head"><p>State</p></th>
<th class="head"><p>Description</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>Left &amp; Right DC Motors spin
clockwise</p></td>
<td><p>Forward</p></td>
</tr>
<tr class="row-odd"><td><p>GPIO5,
GPIO7</p></td>
<td><p>PWM</p></td>
<td><p>Left &amp; Right DC Motors spin
counterclockwise</p></td>
<td><p>Reverse</p></td>
</tr>
<tr class="row-even"><td><p>GPIO6,
GPIO7</p></td>
<td><p>PWM</p></td>
<td><p>Left DC Motors spin clockwise.
Right DC Motors spin counterclockwise</p></td>
<td><p>Left</p></td>
</tr>
<tr class="row-odd"><td><p>GPIO4,
GPIO5</p></td>
<td><p>PWM</p></td>
<td><p>Left DC Motors spin counterclockwise.
Right DC Motors spin clockwise</p></td>
<td><p>Right</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/></section>
</section>
<section id="fusion-of-software-with-hardware">
<h2><span class="section-number">2.2. </span>Fusion of Software with Hardware<a class="headerlink" href="#fusion-of-software-with-hardware" title="Link to this heading"></a></h2>
<p>On one hand, we have the hardware designed so that the joystic x- and y- axis, and DC motors are wired to the proper GPIOs on the
ESP32-C3 WROOM microcontroller. On the other hand, we have the software that reads the joystick x- and y- axis, sends the data
to the receiver device, and converts that to PWM values on the receiver device.</p>
<p>In essense, the direction and speed of the bitByte Rider car is controlled by the two variables. On the remote controller device,
the joystic x- and y- axis values are sent to the receiver device in a raw format (i.e. analog voltages, “as-is”). On the receover
device, these two values are converted to the two PWM values; one for each pair of DC motors on left and right side.</p>
<p>When the joystick is pushed forward, the X-axis voltage remains at 1.65V (neutral), while the Y-axis voltage rises to 3.3V. The
receiver on the RC car interprets this input and generates 100% PWM duty cycle signals on both sides, driving the car forward at
full speed.</p>
<p>Similarly, when the joystick is pushed fully to the left or right, the X-axis voltage shifts while the Y-axis remains neutral. For a
left turn, the receiver translates the signal into 100% PWM on the left-side motors and 0% on the right-side motors, causing the car
to pivot. The opposite occurs for a right turn, with 100% PWM on the right and 0% on the left, enabling precise directional control.</p>
<p>The table below summarizes the reserved GPIOs. These GPIOs are hard-wired to the corresponding components, and hard-coded in the
corresponding functions. For example, the GPIOs 0 and 1 are hard-wired to the joystick x- and y- axis, respectively; and, hard-coded
to read analog values and store them in the corresponding x- and y- variables.</p>
<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><p>NC</p></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>
<p>The struct used to store motor PWM values is shown below. While the bitByteRider RC car can be effectively controlled using
just two PWM signals—one for each side—the structure is designed to hold four values, allowing room for future enhancements. This
forward-thinking design supports potential upgrades such as improved maneuverability, individual wheel control, or advanced driving
modes, making the system more adaptable and scalable for future development.</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>On the transmitter device, the PWM values for the DC motors are sent to the receiver using the following function. The variable
<strong>receiver_mac</strong> stores the MAC address of the receiver device (ESP32-C3 bitBoard on the RC car).</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>This function is invoked by a dedicated FreeRTOS task every 100 milliseconds, ensuring consistent and timely transmission of
control data to the receiver device. By leveraging FreeRTOSs precise task scheduling, the system maintains low-latency
communication and predictable behaviour, critical for real-time control in embedded applications.</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>
<p>As data is being sent, the function onDataSent() is called to check &amp; display the status of the data transmission.</p>
<div class="highlight-c notranslate"><div class="highlight"><pre><span></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>
<span class="p">...</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">...</span>
<span class="p">...</span><span class="w"> </span><span class="p">...</span><span class="w"> </span><span class="p">...</span>
</pre></div>
</div>
<p>On the receiver device, the data is saved in the variables by the call-back function onDataReceived().</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>
</pre></div>
</div>
</section>
<section id="schematic">
<h2><span class="section-number">2.3. </span>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">1. OVERVIEW</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">2. HOW DOES IT WORK?</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#reserved-pins-gpios">2.1. Reserved Pins &amp; GPIOs</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#reading-the-joystick-x-and-y-axis">2.1.1. Reading the Joystick x- and y- axis</a></li>
<li class="toctree-l3"><a class="reference internal" href="#controlling-the-direction-and-speed">2.1.2. Controlling the Direction and Speed</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="#fusion-of-software-with-hardware">2.2. Fusion of Software with Hardware</a></li>
<li class="toctree-l2"><a class="reference internal" href="#schematic">2.3. Schematic</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="data.html">3. DATA STRUCTS</a></li>
<li class="toctree-l1"><a class="reference internal" href="transmitter.html">4. TRANSMITTER</a></li>
<li class="toctree-l1"><a class="reference internal" href="receiver.html">5. RECEIVER</a></li>
<li class="toctree-l1"><a class="reference internal" href="progress.html">6. WORK-IN-PROGRESS WALK THROUGH</a></li>
<li class="toctree-l1"><a class="reference internal" href="references.html">7. 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"><span class="section-number">1. </span>OVERVIEW</a></li>
<li>Next: <a href="data.html" title="next chapter"><span class="section-number">3. </span>DATA STRUCTS</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>