<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://community.element14.com/cfs-file/__key/system/syndication/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"><channel><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690</link><description /><dc:language>en-US</dc:language><generator>Telligent Community 12</generator><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690</link><pubDate>Fri, 14 Nov 2025 17:19:35 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Current Revision posted to Documents by cstanton on 11/14/2025 5:19:35 PM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;In this episode, Milos upgrades his open-source PlatypusBot into Perry the PlatypusBot, transforming a simple Arduino-based rover into a full ROS2-powered robotics platform. He explains how the motor encoders work, implements PID control for precise movement, and connects an Arduino Uno R4 WiFi to a Raspberry Pi 4B running ROS2 Humble for real-time command and control. With a 3D-printed fedora and a name inspired by community feedback, Perry now moves, turns, and responds to ROS commands, laying the groundwork for future additions like sensors, LIDAR, and SLAM.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u9rru80" data-start="308" data-end="727"&gt;Watch the&amp;nbsp;Build&lt;/h2&gt;
&lt;p data-start="308" data-end="727"&gt;&lt;a href="https://youtu.be/Lh4VZpy7In4"&gt;https://youtu.be/Lh4VZpy7In4&lt;/a&gt;&lt;/p&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the PlatypusBot, which earned its name because it was made from scavenged and mismatched parts, &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a Raspberry Pi 4B running ROS2 Humble, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes Perry the PlatypusBot, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9rru81" data-start="949" data-end="981"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u9u9f62" data-start="949" data-end="981"&gt;&lt;img alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/pastedimage1763027396978v3.png" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv70" data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its wheel actuators, brushed DC motors with gearboxes and encoders, ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via Wi-Fi, using an Arduino Uno R4 WiFi and a Python interface on a PC. The&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9uioh3" data-start="1494" data-end="1532"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/Stage1_5F00_Front.PNG" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv71" data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the encoder cage and photodiode sensor used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that six pulses from the encoder equal one millimeter of movement,&amp;nbsp;a neat round number that simplifies control logic.&lt;/p&gt;
&lt;p data-start="1958" data-end="2120"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/3465.salvaged_5F00_parts_5F00_1.4.1.png" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uahq3u7" data-start="2127" data-end="2156"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/2705.jpg" /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv72" data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A 12V battery powers both systems, with a buck converter dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added WAGO connectors for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/RobotDrawing.PNG" /&gt;&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv73" data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing PID controllers (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error, ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;error = reference - measuredSpeed; accumulator += error; output = Kp * error + Ki * accumulator + Kd * (error - lastError); lastError = error;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used hardware interrupts on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;attachInterrupt(digitalPinToInterrupt(2), encoderLeftISR, RISING); attachInterrupt(digitalPinToInterrupt(3), encoderRightISR, RISING);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1j9uag5mh5" data-start="3553" data-end="3574"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/85308.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv74" data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a Raspberry Pi 4B running ROS2 Humble. He explained how ROS structures robot systems around nodes, topics, and services, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using Visual Studio Code remotely connected to the Pi, Milos created a ROS2 service node that sends string commands over serial to the Arduino. The corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="python"&gt;def handle_serial_command(self, request, response): self.serial.write(request.command.encode()) response.success = True response.message = &amp;quot;Command sent&amp;quot; return response&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9uah6rv6" data-start="4812" data-end="4846"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/7178.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv75" data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad, a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both speed and position control worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uaj9f58" data-start="5299" data-end="5331"&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/pastedimage1763028169290v5.png" /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/0257.jpg" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv76" data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a fedora to turn the robot into Perry the PlatypusBot, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden LIDAR, adding SLAM capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a camera and laser pair for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck, meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasising that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u96474b"&gt;Supporting&amp;nbsp;Files and Links&lt;/h2&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/m/files/150702"&gt;Episode 690 Supporting Files&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&lt;span&gt;&lt;a href="https://github.com/ros-realtime/ros-realtime-rpi4-image" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/ros-realtime/ros-realtime-rpi4-image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi8"&gt;Bill of Materials&lt;/h2&gt;
&lt;table class="e14-product-bom-main"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;&lt;a id="e14-product-link-74573" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544,4060368,3051887&amp;nsku=77AK2287,55AK3445,02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_BUY_KIT" class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('74573'));" data-farnell="4208544,4060368,3051887" data-newark="77AK2287,55AK3445,02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Kit&lt;/a&gt; &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino Uno R4 WiFi - ABX00087&lt;/td&gt;
&lt;td&gt;ARDUINO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-db218" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544&amp;nsku=77AK2287&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('db218'));" data-farnell="4208544" data-newark="77AK2287" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L298N Motor Driver - 105990007&lt;/td&gt;
&lt;td&gt;SEEED STUDIO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-d718e" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4060368&amp;nsku=55AK3445&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('d718e'));" data-farnell="4060368" data-newark="55AK3445" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPI4-MODBP-4GB&lt;/td&gt;
&lt;td&gt;RASPBERRY-PI&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-5b700" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=3051887&amp;nsku=02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('5b700'));" data-farnell="3051887" data-newark="02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="SC15185" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="xs-hide"&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi9"&gt;Additional Parts&lt;/h2&gt;
&lt;table class="e14-product-bom-additional"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken/old robot vacuum cleaner&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aluminum 20x20 profile&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery powered drill&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PLA or PETG filament&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3 and M4 screws&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step Down Regulator for powering the Raspberry&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;Over to you - If you&amp;nbsp;could improve one detail in this design, what would it be?&lt;/h2&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/5</link><pubDate>Thu, 13 Nov 2025 10:07:10 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 5 posted to Documents by cstanton on 11/13/2025 10:07:10 AM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;In this episode, Milos upgrades his open-source PlatypusBot into Perry the PlatypusBot, transforming a simple Arduino-based rover into a full ROS2-powered robotics platform. He explains how the motor encoders work, implements PID control for precise movement, and connects an Arduino Uno R4 WiFi to a Raspberry Pi 4B running ROS2 Humble for real-time command and control. With a 3D-printed fedora and a name inspired by community feedback, Perry now moves, turns, and responds to ROS commands, laying the groundwork for future additions like sensors, LIDAR, and SLAM.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u9rru80" data-start="308" data-end="727"&gt;Watch the&amp;nbsp;Build&lt;/h2&gt;
&lt;p data-start="308" data-end="727"&gt;&lt;a href="https://youtu.be/Lh4VZpy7In4"&gt;https://youtu.be/Lh4VZpy7In4&lt;/a&gt;&lt;/p&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the PlatypusBot, which earned its name because it was made from scavenged and mismatched parts, &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a Raspberry Pi 4B running ROS2 Humble, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes Perry the PlatypusBot, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9rru81" data-start="949" data-end="981"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u9u9f62" data-start="949" data-end="981"&gt;&lt;img alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/pastedimage1763027396978v3.png" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv70" data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its wheel actuators, brushed DC motors with gearboxes and encoders, ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via Wi-Fi, using an Arduino Uno R4 WiFi and a Python interface on a PC. The&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9uioh3" data-start="1494" data-end="1532"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/Stage1_5F00_Front.PNG" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv71" data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the encoder cage and photodiode sensor used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that six pulses from the encoder equal one millimeter of movement,&amp;nbsp;a neat round number that simplifies control logic.&lt;/p&gt;
&lt;p data-start="1958" data-end="2120"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/3465.salvaged_5F00_parts_5F00_1.4.1.png" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uahq3u7" data-start="2127" data-end="2156"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/2705.jpg" /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv72" data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A 12V battery powers both systems, with a buck converter dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added WAGO connectors for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/RobotDrawing.PNG" /&gt;&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv73" data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing PID controllers (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error, ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;error = reference - measuredSpeed; accumulator += error; output = Kp * error + Ki * accumulator + Kd * (error - lastError); lastError = error;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used hardware interrupts on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;attachInterrupt(digitalPinToInterrupt(2), encoderLeftISR, RISING); attachInterrupt(digitalPinToInterrupt(3), encoderRightISR, RISING);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1j9uag5mh5" data-start="3553" data-end="3574"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/85308.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv74" data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a Raspberry Pi 4B running ROS2 Humble. He explained how ROS structures robot systems around nodes, topics, and services, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using Visual Studio Code remotely connected to the Pi, Milos created a ROS2 service node that sends string commands over serial to the Arduino. The corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="python"&gt;def handle_serial_command(self, request, response): self.serial.write(request.command.encode()) response.success = True response.message = &amp;quot;Command sent&amp;quot; return response&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9uah6rv6" data-start="4812" data-end="4846"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/7178.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv75" data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad, a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both speed and position control worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uaj9f58" data-start="5299" data-end="5331"&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/pastedimage1763028169290v5.png" /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/0257.jpg" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv76" data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a fedora to turn the robot into Perry the PlatypusBot, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden LIDAR, adding SLAM capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a camera and laser pair for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck, meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasising that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u96474b"&gt;Supporting&amp;nbsp;Files and Links&lt;/h2&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/m/files/150702"&gt;Episode 690 Supporting Files&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&lt;span&gt;&lt;a href="https://github.com/ros-realtime/ros-realtime-rpi4-image" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/ros-realtime/ros-realtime-rpi4-image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi8"&gt;Bill of Materials&lt;/h2&gt;
&lt;table class="e14-product-bom-main"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;&lt;a id="e14-product-link-813a6" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544,4060368,3051887&amp;nsku=77AK2287,55AK3445,02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_BUY_KIT" class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('813a6'));" data-farnell="4208544,4060368,3051887" data-newark="77AK2287,55AK3445,02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Kit&lt;/a&gt; &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino Uno R4 WiFi - ABX00087&lt;/td&gt;
&lt;td&gt;ARDUINO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-44c6f" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544&amp;nsku=77AK2287&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('44c6f'));" data-farnell="4208544" data-newark="77AK2287" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L298N Motor Driver - 105990007&lt;/td&gt;
&lt;td&gt;SEEED STUDIO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-4e828" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4060368&amp;nsku=55AK3445&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('4e828'));" data-farnell="4060368" data-newark="55AK3445" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPI4-MODBP-4GB&lt;/td&gt;
&lt;td&gt;RASPBERRY-PI&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-b4b97" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=3051887&amp;nsku=02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('b4b97'));" data-farnell="3051887" data-newark="02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="SC15185" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="xs-hide"&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi9"&gt;Additional Parts&lt;/h2&gt;
&lt;table class="e14-product-bom-additional"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken/old robot vacuum cleaner&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aluminum 20x20 profile&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery powered drill&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PLA or PETG filament&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3 and M4 screws&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step Down Regulator for powering the Raspberry&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="mcetoc_1j9u95fsia"&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/6</link><pubDate>Thu, 13 Nov 2025 10:07:10 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>e14sbhargav</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 6 posted to Documents by e14sbhargav on 11/13/2025 10:07:10 AM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;In this episode, Milos upgrades his open-source PlatypusBot into Perry the PlatypusBot, transforming a simple Arduino-based rover into a full ROS2-powered robotics platform. He explains how the motor encoders work, implements PID control for precise movement, and connects an Arduino Uno R4 WiFi to a Raspberry Pi 4B running ROS2 Humble for real-time command and control. With a 3D-printed fedora and a name inspired by community feedback, Perry now moves, turns, and responds to ROS commands, laying the groundwork for future additions like sensors, LIDAR, and SLAM.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u9rru80" data-start="308" data-end="727"&gt;Watch the&amp;nbsp;Build&lt;/h2&gt;
&lt;p data-start="308" data-end="727"&gt;&lt;a href="https://youtu.be/Lh4VZpy7In4"&gt;https://youtu.be/Lh4VZpy7In4&lt;/a&gt;&lt;/p&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the PlatypusBot, which earned its name because it was made from scavenged and mismatched parts, &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a Raspberry Pi 4B running ROS2 Humble, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes Perry the PlatypusBot, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9rru81" data-start="949" data-end="981"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u9u9f62" data-start="949" data-end="981"&gt;&lt;img alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/pastedimage1763027396978v3.png" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv70" data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its wheel actuators, brushed DC motors with gearboxes and encoders, ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via Wi-Fi, using an Arduino Uno R4 WiFi and a Python interface on a PC. The&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9uioh3" data-start="1494" data-end="1532"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/Stage1_5F00_Front.PNG" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv71" data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the encoder cage and photodiode sensor used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that six pulses from the encoder equal one millimeter of movement,&amp;nbsp;a neat round number that simplifies control logic.&lt;/p&gt;
&lt;p data-start="1958" data-end="2120"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/3465.salvaged_5F00_parts_5F00_1.4.1.png" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uahq3u7" data-start="2127" data-end="2156"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/2705.jpg" /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv72" data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A 12V battery powers both systems, with a buck converter dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added WAGO connectors for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/RobotDrawing.PNG" /&gt;&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv73" data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing PID controllers (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error, ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;error = reference - measuredSpeed; accumulator += error; output = Kp * error + Ki * accumulator + Kd * (error - lastError); lastError = error;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used hardware interrupts on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;attachInterrupt(digitalPinToInterrupt(2), encoderLeftISR, RISING); attachInterrupt(digitalPinToInterrupt(3), encoderRightISR, RISING);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1j9uag5mh5" data-start="3553" data-end="3574"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/85308.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv74" data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a Raspberry Pi 4B running ROS2 Humble. He explained how ROS structures robot systems around nodes, topics, and services, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using Visual Studio Code remotely connected to the Pi, Milos created a ROS2 service node that sends string commands over serial to the Arduino. The corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="python"&gt;def handle_serial_command(self, request, response): self.serial.write(request.command.encode()) response.success = True response.message = &amp;quot;Command sent&amp;quot; return response&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9uah6rv6" data-start="4812" data-end="4846"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/7178.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv75" data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad, a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both speed and position control worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uaj9f58" data-start="5299" data-end="5331"&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/pastedimage1763028169290v5.png" /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-03-81/0257.jpg" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv76" data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a fedora to turn the robot into Perry the PlatypusBot, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden LIDAR, adding SLAM capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a camera and laser pair for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck, meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasising that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u96474b"&gt;Supporting&amp;nbsp;Files and Links&lt;/h2&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/m/files/150702"&gt;Episode 690 Supporting Files&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&lt;span&gt;&lt;a href="https://github.com/ros-realtime/ros-realtime-rpi4-image" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/ros-realtime/ros-realtime-rpi4-image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi8"&gt;Bill of Materials&lt;/h2&gt;
&lt;table class="e14-product-bom-main"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;&lt;a id="e14-product-link-68164" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544,4060368,3051887&amp;nsku=77AK2287,55AK3445,02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_BUY_KIT" class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('68164'));" data-farnell="4208544,4060368,3051887" data-newark="77AK2287,55AK3445,02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Kit&lt;/a&gt; &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino Uno R4 WiFi - ABX00087&lt;/td&gt;
&lt;td&gt;ARDUINO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-6fb97" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544&amp;nsku=77AK2287&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('6fb97'));" data-farnell="4208544" data-newark="77AK2287" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L298N Motor Driver - 105990007&lt;/td&gt;
&lt;td&gt;SEEED STUDIO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-bdb21" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4060368&amp;nsku=55AK3445&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('bdb21'));" data-farnell="4060368" data-newark="55AK3445" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPI4-MODBP-4GB&lt;/td&gt;
&lt;td&gt;RASPBERRY-PI&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-67761" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=3051887&amp;nsku=02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('67761'));" data-farnell="3051887" data-newark="02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="SC15185" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="xs-hide"&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi9"&gt;Additional Parts&lt;/h2&gt;
&lt;table class="e14-product-bom-additional"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken/old robot vacuum cleaner&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aluminum 20x20 profile&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery powered drill&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PLA or PETG filament&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3 and M4 screws&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step Down Regulator for powering the Raspberry&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="mcetoc_1j9u95fsia"&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/4</link><pubDate>Thu, 13 Nov 2025 10:04:58 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 4 posted to Documents by cstanton on 11/13/2025 10:04:58 AM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;In this episode, Milos upgrades his open-source PlatypusBot into Perry the PlatypusBot, transforming a simple Arduino-based rover into a full ROS2-powered robotics platform. He explains how the motor encoders work, implements PID control for precise movement, and connects an Arduino Uno R4 WiFi to a Raspberry Pi 4B running ROS2 Humble for real-time command and control. With a 3D-printed fedora and a name inspired by community feedback, Perry now moves, turns, and responds to ROS commands, laying the groundwork for future additions like sensors, LIDAR, and SLAM.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u9rru80" data-start="308" data-end="727"&gt;Watch the&amp;nbsp;Build&lt;/h2&gt;
&lt;p data-start="308" data-end="727"&gt;&lt;/p&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the PlatypusBot, which earned its name because it was made from scavenged and mismatched parts, &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a Raspberry Pi 4B running ROS2 Humble, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes Perry the PlatypusBot, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9rru81" data-start="949" data-end="981"&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u9u9f62" data-start="949" data-end="981"&gt;&lt;img alt="image" style="max-height:360px;max-width:640px;" src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/pastedimage1763027396978v3.png"  /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv70" data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its wheel actuators, brushed DC motors with gearboxes and encoders, ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via Wi-Fi, using an Arduino Uno R4 WiFi and a Python interface on a PC. The&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u9uioh3" data-start="1494" data-end="1532"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/Stage1_5F00_Front.PNG" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv71" data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the encoder cage and photodiode sensor used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that six pulses from the encoder equal one millimeter of movement,&amp;nbsp;a neat round number that simplifies control logic.&lt;/p&gt;
&lt;p data-start="1958" data-end="2120"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/3465.salvaged_5F00_parts_5F00_1.4.1.png" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uahq3u7" data-start="2127" data-end="2156"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/2705.jpg" /&gt;&lt;/h2&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv72" data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A 12V battery powers both systems, with a buck converter dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added WAGO connectors for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/RobotDrawing.PNG" /&gt;&lt;/p&gt;
&lt;p data-start="2536" data-end="2652"&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv73" data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing PID controllers (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error, ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;error = reference - measuredSpeed; accumulator += error; output = Kp * error + Ki * accumulator + Kd * (error - lastError); lastError = error;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used hardware interrupts on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="c_cpp"&gt;attachInterrupt(digitalPinToInterrupt(2), encoderLeftISR, RISING); attachInterrupt(digitalPinToInterrupt(3), encoderRightISR, RISING);&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 id="mcetoc_1j9uag5mh5" data-start="3553" data-end="3574"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/85308.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv74" data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a Raspberry Pi 4B running ROS2 Humble. He explained how ROS structures robot systems around nodes, topics, and services, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using Visual Studio Code remotely connected to the Pi, Milos created a ROS2 service node that sends string commands over serial to the Arduino. The corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;pre class="ui-code" data-mode="python"&gt;def handle_serial_command(self, request, response): self.serial.write(request.command.encode()) response.success = True response.message = &amp;quot;Command sent&amp;quot; return response&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9uah6rv6" data-start="4812" data-end="4846"&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/7178.jpg" /&gt;&lt;/h2&gt;
&lt;h2 id="mcetoc_1j9u93hv75" data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad, a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both speed and position control worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;h2 id="mcetoc_1j9uaj9f58" data-start="5299" data-end="5331"&gt;&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;" src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/pastedimage1763028169290v5.png"  /&gt;&lt;img loading="lazy" alt="image" style="max-height:360px;max-width:640px;"  src="/resized-image/__size/1280x720/__key/communityserver-wikis-components-files/00-00-00-04-35/0257.jpg" /&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u93hv76" data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a fedora to turn the robot into Perry the PlatypusBot, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden LIDAR, adding SLAM capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a camera and laser pair for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck, meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasising that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u96474b"&gt;Supporting&amp;nbsp;Files and Links&lt;/h2&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/m/files/150702"&gt;Episode 690 Supporting Files&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71934/platypusbot---scavenging-for-robotics-parts----episode-671"&gt;PlatypusBot - Scavenging for Robotics Parts -- Episode 671&lt;/a&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&lt;span&gt;&lt;a href="https://github.com/ros-realtime/ros-realtime-rpi4-image" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://github.com/ros-realtime/ros-realtime-rpi4-image&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;-&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;a href="https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments" rel="noopener noreferrer nofollow" target="_blank" data-e14adj="t"&gt;https://www.printables.com/model/477316-perry-the-platypus-speaker-attachments&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi8"&gt;Bill of Materials&lt;/h2&gt;
&lt;table class="e14-product-bom-main"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;&lt;a id="e14-product-link-21400" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544,4060368,3051887&amp;nsku=77AK2287,55AK3445,02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_BUY_KIT" class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('21400'));" data-farnell="4208544,4060368,3051887" data-newark="77AK2287,55AK3445,02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Kit&lt;/a&gt; &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino Uno R4 WiFi - ABX00087&lt;/td&gt;
&lt;td&gt;ARDUINO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-53f5d" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544&amp;nsku=77AK2287&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('53f5d'));" data-farnell="4208544" data-newark="77AK2287" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L298N Motor Driver - 105990007&lt;/td&gt;
&lt;td&gt;SEEED STUDIO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-d2600" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4060368&amp;nsku=55AK3445&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('d2600'));" data-farnell="4060368" data-newark="55AK3445" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPI4-MODBP-4GB&lt;/td&gt;
&lt;td&gt;RASPBERRY-PI&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-f4702" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=3051887&amp;nsku=02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('f4702'));" data-farnell="3051887" data-newark="02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="SC15185" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="xs-hide"&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi9"&gt;Additional Parts&lt;/h2&gt;
&lt;table class="e14-product-bom-additional"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken/old robot vacuum cleaner&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aluminum 20x20 profile&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery powered drill&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PLA or PETG filament&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3 and M4 screws&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step Down Regulator for powering the Raspberry&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="mcetoc_1j9u95fsia"&gt;&lt;/h3&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/3</link><pubDate>Thu, 13 Nov 2025 09:36:47 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 3 posted to Documents by cstanton on 11/13/2025 9:36:47 AM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the &lt;strong data-start="384" data-end="399"&gt;PlatypusBot&lt;/strong&gt;, which earned its name because it was made from scavenged and mismatched parts &amp;mdash; &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a &lt;strong data-start="530" data-end="549"&gt;Raspberry Pi 4B&lt;/strong&gt; running &lt;strong data-start="558" data-end="573"&gt;ROS2 Humble&lt;/strong&gt;, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes &lt;strong data-start="677" data-end="702"&gt;Perry the PlatypusBot&lt;/strong&gt;, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="944" data-end="947" /&gt;
&lt;h2 id="mcetoc_1j9u93hv70" data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its &lt;strong data-start="1073" data-end="1092"&gt;wheel actuators&lt;/strong&gt; &amp;mdash; brushed DC motors with gearboxes and encoders &amp;mdash; ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via &lt;strong data-start="1259" data-end="1268"&gt;Wi-Fi&lt;/strong&gt;, using an &lt;strong data-start="1279" data-end="1302"&gt;Arduino Uno R4 WiFi&lt;/strong&gt; and a Python interface on a PC.&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="1489" data-end="1492" /&gt;
&lt;h2 id="mcetoc_1j9u93hv71" data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the &lt;strong data-start="1621" data-end="1637"&gt;encoder cage&lt;/strong&gt; and &lt;strong data-start="1642" data-end="1663"&gt;photodiode sensor&lt;/strong&gt; used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that &lt;strong data-start="2003" data-end="2067"&gt;six pulses from the encoder equal one millimeter of movement&lt;/strong&gt; &amp;mdash; a neat round number that simplifies control logic.&lt;/p&gt;
&lt;hr data-start="2122" data-end="2125" /&gt;
&lt;h2 id="mcetoc_1j9u93hv72" data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A &lt;strong data-start="2206" data-end="2221"&gt;12V battery&lt;/strong&gt; powers both systems, with a &lt;strong data-start="2250" data-end="2268"&gt;buck converter&lt;/strong&gt; dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added &lt;strong data-start="2565" data-end="2584"&gt;WAGO connectors&lt;/strong&gt; for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;hr data-start="2654" data-end="2657" /&gt;
&lt;h2 id="mcetoc_1j9u93hv73" data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing &lt;strong data-start="2751" data-end="2770"&gt;PID controllers&lt;/strong&gt; (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error &amp;mdash; ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-c"&gt;&lt;span&gt;error = reference - measuredSpeed;
accumulator += error;
output = Kp * error + Ki * accumulator + Kd * (error - lastError);
lastError = error;
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used &lt;strong data-start="3322" data-end="3345"&gt;hardware interrupts&lt;/strong&gt; on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-c"&gt;&lt;span&gt;attachInterrupt(digitalPinToInterrupt(&lt;span class="hljs-number"&gt;2&lt;/span&gt;), encoderLeftISR, RISING);
attachInterrupt(digitalPinToInterrupt(&lt;span class="hljs-number"&gt;3&lt;/span&gt;), encoderRightISR, RISING);
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-start="3548" data-end="3551" /&gt;
&lt;h2 id="mcetoc_1j9u93hv74" data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a &lt;strong data-start="3639" data-end="3658"&gt;Raspberry Pi 4B&lt;/strong&gt; running &lt;strong data-start="3667" data-end="3682"&gt;ROS2 Humble&lt;/strong&gt;. He explained how ROS structures robot systems around &lt;strong data-start="3737" data-end="3746"&gt;nodes&lt;/strong&gt;, &lt;strong data-start="3748" data-end="3758"&gt;topics&lt;/strong&gt;, and &lt;strong data-start="3764" data-end="3776"&gt;services&lt;/strong&gt;, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using &lt;strong data-start="4005" data-end="4027"&gt;Visual Studio Code&lt;/strong&gt; remotely connected to the Pi, Milos created a &lt;strong data-start="4074" data-end="4095"&gt;ROS2 service node&lt;/strong&gt; that sends string commands over serial to the Arduino.&lt;br data-start="4150" data-end="4153" /&gt; Example service definition:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-python"&gt;&lt;span&gt;&lt;span class="hljs-comment"&gt;# StringCommand.srv&lt;/span&gt;
string command
---
&lt;span class="hljs-built_in"&gt;bool&lt;/span&gt; success
string message
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4264" data-end="4304"&gt;And the corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-python"&gt;&lt;span&gt;&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title function_"&gt;handle_serial_command&lt;/span&gt;(&lt;span class="hljs-params"&gt;self, request, response&lt;/span&gt;):
    self.serial.write(request.command.encode())
    response.success = &lt;span class="hljs-literal"&gt;True&lt;/span&gt;
    response.message = &lt;span class="hljs-string"&gt;&amp;quot;Command sent&amp;quot;&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; response
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="4807" data-end="4810" /&gt;
&lt;h2 id="mcetoc_1j9u93hv75" data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad &amp;mdash; a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both &lt;strong data-start="5208" data-end="5217"&gt;speed&lt;/strong&gt; and &lt;strong data-start="5222" data-end="5242"&gt;position control&lt;/strong&gt; worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;hr data-start="5294" data-end="5297" /&gt;
&lt;h2 id="mcetoc_1j9u93hv76" data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a &lt;strong data-start="5368" data-end="5378"&gt;fedora&lt;/strong&gt; to turn the robot into &lt;strong data-start="5402" data-end="5427"&gt;Perry the PlatypusBot&lt;/strong&gt;, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden &lt;strong data-start="5554" data-end="5563"&gt;LIDAR&lt;/strong&gt;, adding &lt;strong data-start="5572" data-end="5580"&gt;SLAM&lt;/strong&gt; capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a &lt;strong data-start="5630" data-end="5655"&gt;camera and laser pair&lt;/strong&gt; for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck &amp;mdash; meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="5810" data-end="5813" /&gt;
&lt;h2 id="mcetoc_1j9u93hv77" data-start="5815" data-end="5827"&gt;Closing&lt;/h2&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasizing that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="mcetoc_1j9u96474b"&gt;Supporting&amp;nbsp;Files and Links&lt;/h2&gt;
&lt;p&gt;-&amp;nbsp;&amp;nbsp;&lt;a href="https://community.element14.com/challenges-projects/element14-presents/m/files/150702"&gt;Episode 690 Supporting Files&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi8"&gt;Bill of Materials&lt;/h2&gt;
&lt;table class="e14-product-bom-main"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;th&gt;&lt;a id="e14-product-link-6ba31" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544,4060368,3051887&amp;nsku=77AK2287,55AK3445,02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_BUY_KIT" class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('6ba31'));" data-farnell="4208544,4060368,3051887" data-newark="77AK2287,55AK3445,02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Kit&lt;/a&gt; &lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Arduino Uno R4 WiFi - ABX00087&lt;/td&gt;
&lt;td&gt;ARDUINO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-dcd66" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4208544&amp;nsku=77AK2287&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('dcd66'));" data-farnell="4208544" data-newark="77AK2287" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L298N Motor Driver - 105990007&lt;/td&gt;
&lt;td&gt;SEEED STUDIO&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-772a3" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=4060368&amp;nsku=55AK3445&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('772a3'));" data-farnell="4060368" data-newark="55AK3445" data-comoverride="" data-cmpoverride="" data-cpc="" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RPI4-MODBP-4GB&lt;/td&gt;
&lt;td&gt;RASPBERRY-PI&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;a id="e14-product-link-f8170" data-at-areainteracted="rte-content" data-at-type="click" data-at-link-type="button" href="https://referral.element14.com/OrderCodeView?fsku=3051887&amp;nsku=02AH3164&amp;COM=e14c-noscript&amp;CMP=e14c-noscript&amp;osetc=e14-noscript-tracking-loss" data-at-label="PRODUCT_POPUP_OPEN"class="e14-embedded e14_shopping-cart-far e14-button" onclick="event.preventDefault();e14.func.displayProduct(e14.meta.user.country, this, 'embedded-link', e14.func.getProductLinkJSON('f8170'));" data-farnell="3051887" data-newark="02AH3164" data-comoverride="" data-cmpoverride="" data-cpc="SC15185" data-avnetemea="" data-avnetema="" data-avnetasia="" &gt;Buy Now&lt;/a&gt; &lt;/td&gt;
&lt;/tr&gt;
&lt;tr class="xs-hide"&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h2 id="mcetoc_1j9u95fsi9"&gt;Additional Parts&lt;/h2&gt;
&lt;table class="e14-product-bom-additional"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Product Name&lt;/th&gt;
&lt;th&gt;Manufacturer&lt;/th&gt;
&lt;th&gt;Quantity&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Broken/old robot vacuum cleaner&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Aluminum 20x20 profile&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Battery powered drill&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PLA or PETG filament&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M3 and M4 screws&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Step Down Regulator for powering the Raspberry&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="mcetoc_1j9u95fsia"&gt;&lt;/h3&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/2</link><pubDate>Thu, 13 Nov 2025 09:28:22 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 2 posted to Documents by cstanton on 11/13/2025 9:28:22 AM&lt;br /&gt;
&lt;p data-start="308" data-end="727"&gt;Milos continues work on his small open-source mobile robotics platform, the &lt;strong data-start="384" data-end="399"&gt;PlatypusBot&lt;/strong&gt;, which earned its name because it was made from scavenged and mismatched parts &amp;mdash; &amp;ldquo;just like a platypus.&amp;rdquo; In this stage, he adds a &lt;strong data-start="530" data-end="549"&gt;Raspberry Pi 4B&lt;/strong&gt; running &lt;strong data-start="558" data-end="573"&gt;ROS2 Humble&lt;/strong&gt;, transforming the robot into a true robotics platform. To top it off, the robot now officially becomes &lt;strong data-start="677" data-end="702"&gt;Perry the PlatypusBot&lt;/strong&gt;, complete with a fedora.&lt;/p&gt;
&lt;blockquote data-start="729" data-end="942"&gt;
&lt;p data-start="731" data-end="942"&gt;&amp;ldquo;Today we will continue work on our platypus bot from last time. This time are going to learn about encoders, we&amp;rsquo;re going to learn about PID controllers, and we&amp;rsquo;re going to make some highly requested additions.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="944" data-end="947" /&gt;
&lt;h2 data-start="949" data-end="981"&gt;Recap of the Previous Stage&lt;/h2&gt;
&lt;p data-start="982" data-end="1176"&gt;Previously, Milos dismantled a broken robot vacuum cleaner purchased online and reused its &lt;strong data-start="1073" data-end="1092"&gt;wheel actuators&lt;/strong&gt; &amp;mdash; brushed DC motors with gearboxes and encoders &amp;mdash; ideal for a small mobile robot.&lt;/p&gt;
&lt;p data-start="1178" data-end="1334"&gt;He finished that stage with a joystick-controlled robot that could be driven via &lt;strong data-start="1259" data-end="1268"&gt;Wi-Fi&lt;/strong&gt;, using an &lt;strong data-start="1279" data-end="1302"&gt;Arduino Uno R4 WiFi&lt;/strong&gt; and a Python interface on a PC.&lt;/p&gt;
&lt;blockquote data-start="1336" data-end="1487"&gt;
&lt;p data-start="1338" data-end="1487"&gt;&amp;ldquo;This is a small mobile robot platform made from discarded parts from an old Roomba&amp;hellip; controlled by a joystick or Wi-Fi using an Arduino Uno R4 WiFi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="1489" data-end="1492" /&gt;
&lt;h2 data-start="1494" data-end="1532"&gt;Mechanical Breakdown and Encoders&lt;/h2&gt;
&lt;p data-start="1533" data-end="1799"&gt;To better understand the actuators, Milos disassembled one of the motors, revealing the &lt;strong data-start="1621" data-end="1637"&gt;encoder cage&lt;/strong&gt; and &lt;strong data-start="1642" data-end="1663"&gt;photodiode sensor&lt;/strong&gt; used to measure rotation and speed. The gearing ratios and encoder counts were calculated precisely to allow accurate movement control.&lt;/p&gt;
&lt;blockquote data-start="1801" data-end="1956"&gt;
&lt;p data-start="1803" data-end="1956"&gt;&amp;ldquo;You can imagine the teeth coming between them and they&amp;rsquo;re breaking the signal. That&amp;rsquo;s what we use to actually know the position and speed of the motor.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="1958" data-end="2120"&gt;Through his calculations, he determined that &lt;strong data-start="2003" data-end="2067"&gt;six pulses from the encoder equal one millimeter of movement&lt;/strong&gt; &amp;mdash; a neat round number that simplifies control logic.&lt;/p&gt;
&lt;hr data-start="2122" data-end="2125" /&gt;
&lt;h2 data-start="2127" data-end="2156"&gt;Building the Electronics&lt;/h2&gt;
&lt;p data-start="2157" data-end="2390"&gt;The electronics remained simple but effective. A &lt;strong data-start="2206" data-end="2221"&gt;12V battery&lt;/strong&gt; powers both systems, with a &lt;strong data-start="2250" data-end="2268"&gt;buck converter&lt;/strong&gt; dropping voltage to 5V for the Raspberry Pi. The encoders are read through pull-up resistors and an optical sensing pair.&lt;/p&gt;
&lt;blockquote data-start="2392" data-end="2534"&gt;
&lt;p data-start="2394" data-end="2534"&gt;&amp;ldquo;Everything is powered by a 12 volt battery, but this time I added a buck converter to step that down to five volts so we can power the Pi.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="2536" data-end="2652"&gt;For convenience, Milos added &lt;strong data-start="2565" data-end="2584"&gt;WAGO connectors&lt;/strong&gt; for modular disconnection, keeping the system neat and serviceable.&lt;/p&gt;
&lt;hr data-start="2654" data-end="2657" /&gt;
&lt;h2 data-start="2659" data-end="2690"&gt;PID Control Implementation&lt;/h2&gt;
&lt;p data-start="2691" data-end="2915"&gt;Precise control of speed and distance required implementing &lt;strong data-start="2751" data-end="2770"&gt;PID controllers&lt;/strong&gt; (Proportional&amp;ndash;Integral&amp;ndash;Derivative). Milos demonstrated how each term influences stability and responsiveness before applying it in Arduino code.&lt;/p&gt;
&lt;blockquote data-start="2917" data-end="3019"&gt;
&lt;p data-start="2919" data-end="3019"&gt;&amp;ldquo;The purpose of the PID controller is to actually minimize that error &amp;mdash; ideally to have it at zero.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3021" data-end="3085"&gt;A simplified version of his Arduino code illustrates this logic:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-c"&gt;&lt;span&gt;error = reference - measuredSpeed;
accumulator += error;
output = Kp * error + Ki * accumulator + Kd * (error - lastError);
lastError = error;
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="3240" data-end="3401"&gt;The result was reliable control of each wheel&amp;rsquo;s velocity and position. Milos used &lt;strong data-start="3322" data-end="3345"&gt;hardware interrupts&lt;/strong&gt; on pins 2 and 3 to read the encoder pulses efficiently.&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-c"&gt;&lt;span&gt;attachInterrupt(digitalPinToInterrupt(&lt;span class="hljs-number"&gt;2&lt;/span&gt;), encoderLeftISR, RISING);
attachInterrupt(digitalPinToInterrupt(&lt;span class="hljs-number"&gt;3&lt;/span&gt;), encoderRightISR, RISING);
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-start="3548" data-end="3551" /&gt;
&lt;h2 data-start="3553" data-end="3574"&gt;ROS2 Integration&lt;/h2&gt;
&lt;p data-start="3575" data-end="3809"&gt;With the fundamentals working, Milos connected the Arduino to a &lt;strong data-start="3639" data-end="3658"&gt;Raspberry Pi 4B&lt;/strong&gt; running &lt;strong data-start="3667" data-end="3682"&gt;ROS2 Humble&lt;/strong&gt;. He explained how ROS structures robot systems around &lt;strong data-start="3737" data-end="3746"&gt;nodes&lt;/strong&gt;, &lt;strong data-start="3748" data-end="3758"&gt;topics&lt;/strong&gt;, and &lt;strong data-start="3764" data-end="3776"&gt;services&lt;/strong&gt;, allowing modular communication.&lt;/p&gt;
&lt;blockquote data-start="3811" data-end="3997"&gt;
&lt;p data-start="3813" data-end="3997"&gt;&amp;ldquo;Imagine nodes as independent parts of code running in a loop. Topics are message channels through which you can publish or subscribe to data, and services are event-based interfaces.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="3999" data-end="4180"&gt;Using &lt;strong data-start="4005" data-end="4027"&gt;Visual Studio Code&lt;/strong&gt; remotely connected to the Pi, Milos created a &lt;strong data-start="4074" data-end="4095"&gt;ROS2 service node&lt;/strong&gt; that sends string commands over serial to the Arduino.&lt;br data-start="4150" data-end="4153" /&gt; Example service definition:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-python"&gt;&lt;span&gt;&lt;span class="hljs-comment"&gt;# StringCommand.srv&lt;/span&gt;
string command
---
&lt;span class="hljs-built_in"&gt;bool&lt;/span&gt; success
string message
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4264" data-end="4304"&gt;And the corresponding handler in Python:&lt;/p&gt;
&lt;div class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"&gt;
&lt;div class="sticky top-9"&gt;
&lt;div class="absolute end-0 bottom-0 flex h-9 items-center pe-2"&gt;
&lt;div class="bg-token-bg-elevated-secondary text-token-text-secondary flex items-center gap-4 rounded-sm px-2 font-sans text-xs"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="overflow-y-auto p-4" dir="ltr"&gt;&lt;code class="whitespace-pre! language-python"&gt;&lt;span&gt;&lt;span class="hljs-keyword"&gt;def&lt;/span&gt; &lt;span class="hljs-title function_"&gt;handle_serial_command&lt;/span&gt;(&lt;span class="hljs-params"&gt;self, request, response&lt;/span&gt;):
    self.serial.write(request.command.encode())
    response.success = &lt;span class="hljs-literal"&gt;True&lt;/span&gt;
    response.message = &lt;span class="hljs-string"&gt;&amp;quot;Command sent&amp;quot;&lt;/span&gt;
    &lt;span class="hljs-keyword"&gt;return&lt;/span&gt; response
&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-start="4507" data-end="4561"&gt;This setup allowed simple high-level commands such as:&lt;/p&gt;
&lt;ul data-start="4562" data-end="4639"&gt;
&lt;li data-start="4562" data-end="4585"&gt;
&lt;p data-start="4564" data-end="4585"&gt;Move a set distance&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4586" data-end="4611"&gt;
&lt;p data-start="4588" data-end="4611"&gt;Turn a specific angle&lt;/p&gt;
&lt;/li&gt;
&lt;li data-start="4612" data-end="4639"&gt;
&lt;p data-start="4614" data-end="4639"&gt;Maintain constant speed&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-start="4641" data-end="4805"&gt;
&lt;p data-start="4643" data-end="4805"&gt;&amp;ldquo;In the end, Perry the Platypus could follow simple commands like keeping constant speed, moving a set number of millimeters, or turning a set number of degrees.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="4807" data-end="4810" /&gt;
&lt;h2 data-start="4812" data-end="4846"&gt;Testing Perry the PlatypusBot&lt;/h2&gt;
&lt;p data-start="4847" data-end="5026"&gt;After assembling everything, Milos demonstrated Perry&amp;rsquo;s movements using ROS commands. The robot could drive forward, reverse, and spin accurately according to programmed commands.&lt;/p&gt;
&lt;blockquote data-start="5028" data-end="5174"&gt;
&lt;p data-start="5030" data-end="5174"&gt;&amp;ldquo;You can see Perry moving and actually stopping, not bad &amp;mdash; a few millimeters before the line. That&amp;rsquo;s because of the accuracy of the controller.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-start="5176" data-end="5292"&gt;The testing validated that both &lt;strong data-start="5208" data-end="5217"&gt;speed&lt;/strong&gt; and &lt;strong data-start="5222" data-end="5242"&gt;position control&lt;/strong&gt; worked properly across the ROS&amp;ndash;Arduino interface.&lt;/p&gt;
&lt;hr data-start="5294" data-end="5297" /&gt;
&lt;h2 data-start="5299" data-end="5331"&gt;The Fedora and Future Plans&lt;/h2&gt;
&lt;p data-start="5332" data-end="5684"&gt;By popular request, Milos printed a &lt;strong data-start="5368" data-end="5378"&gt;fedora&lt;/strong&gt; to turn the robot into &lt;strong data-start="5402" data-end="5427"&gt;Perry the PlatypusBot&lt;/strong&gt;, using a model from Printables and adapting it to fit over the LIDAR module.&lt;br data-start="5504" data-end="5507" /&gt; Future upgrades include integrating the hidden &lt;strong data-start="5554" data-end="5563"&gt;LIDAR&lt;/strong&gt;, adding &lt;strong data-start="5572" data-end="5580"&gt;SLAM&lt;/strong&gt; capabilities, and possibly using the &amp;ldquo;eyes&amp;rdquo; as a &lt;strong data-start="5630" data-end="5655"&gt;camera and laser pair&lt;/strong&gt; for vision-based navigation.&lt;/p&gt;
&lt;blockquote data-start="5686" data-end="5808"&gt;
&lt;p data-start="5688" data-end="5808"&gt;&amp;ldquo;Since it&amp;rsquo;s named Platypus Bot, and since I actually guessed the color completely by luck &amp;mdash; meet Perry the PlatypusBot!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr data-start="5810" data-end="5813" /&gt;
&lt;h2 data-start="5815" data-end="5827"&gt;Closing&lt;/h2&gt;
&lt;p data-start="5828" data-end="5997"&gt;Milos concluded this stage by emphasizing that this was a foundation for future iterations involving faster communication, sensor integration, and autonomous navigation.&lt;/p&gt;
&lt;blockquote data-start="5999" data-end="6196"&gt;
&lt;p data-start="6001" data-end="6196"&gt;&amp;ldquo;Thanks so much for watching Perry the PlatypusBot Stage Two. We&amp;rsquo;ve added the Raspberry Pi 4 running ROS2 Humble, communicating with an Arduino Uno, sending commands for precise wheel movements.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Supporting&amp;nbsp;Files and Links&lt;/p&gt;
&lt;p&gt;-&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;div style="clear:both;"&gt;&lt;/div&gt;

&lt;div style="font-size: 90%;"&gt;Tags: arduino raspberry pi integration, Robot operating System, pid controller arduino, ros2 humble, raspberry pi 4b, open source robot, brushed dc motor encoder, encoder motor control, diy robotics project, mobile robot platform, arduino uno r4 wifi, robot control systems, diy autonomous robot, robotics with ros2, arduino robot build&lt;/div&gt;
</description></item><item><title>Meet the PlatypusBot: Now Powered by Raspberry Pi &amp; ROS -- Episode 690</title><link>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690/revision/1</link><pubDate>Thu, 13 Nov 2025 09:08:28 GMT</pubDate><guid isPermaLink="false">93d5dcb4-84c2-446f-b2cb-99731719e767:d3cac9a9-cafc-43e1-a828-7af0d90d80f3</guid><dc:creator>cstanton</dc:creator><comments>https://community.element14.com/challenges-projects/element14-presents/project-videos/w/documents/71993/meet-the-platypusbot-now-powered-by-raspberry-pi-ros----episode-690#comments</comments><description>Revision 1 posted to Documents by cstanton on 11/13/2025 9:08:28 AM&lt;br /&gt;
&lt;p&gt;1&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;
</description></item></channel></rss>