<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Prototyping | Antoine Weill--Duflos</title>
    <link>https://antoine.weill-duflos.fr/en/tag/prototyping/</link>
      <atom:link href="https://antoine.weill-duflos.fr/en/tag/prototyping/index.xml" rel="self" type="application/rss+xml" />
    <description>Prototyping</description>
    <generator>Hugo Blox Builder (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Tue, 13 Oct 2026 00:00:00 +0000</lastBuildDate>
    <image>
      <url>https://antoine.weill-duflos.fr/media/icon_hu_d686267daab28486.png</url>
      <title>Prototyping</title>
      <link>https://antoine.weill-duflos.fr/en/tag/prototyping/</link>
    </image>
    
    <item>
      <title>A Pocket Rolling Stone, Part 3: The PCBs Arrive, and the Ball Comes Back</title>
      <link>https://antoine.weill-duflos.fr/en/post/esp32-rolling-stone-pcb/</link>
      <pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate>
      <guid>https://antoine.weill-duflos.fr/en/post/esp32-rolling-stone-pcb/</guid>
      <description>&lt;p&gt;The boards arrived. I plugged them in, flashed them, tested them: &lt;strong&gt;they work&lt;/strong&gt;. After the separate modules, the wires, and the small enclosure wrapped around the first prototype, the rolling stone now has a dedicated printed circuit board.&lt;/p&gt;
&lt;p&gt;In &lt;a href=&#34;../esp32-rolling-stone/&#34;&gt;Part 1&lt;/a&gt;, I described the physics and the I2S audio build. In &lt;a href=&#34;../esp32-rolling-stone-hbridge/&#34;&gt;Part 2&lt;/a&gt;, I moved to an H-bridge and a version I actually put in a handheld enclosure. This time, the adventure runs between the schematic, the JLCPCB order, and the return to the bench. The ball is still virtual; the electronics giving it weight in the hand are becoming rather more tangible.&lt;/p&gt;
&lt;h2 id=&#34;from-modules-to-a-dedicated-board&#34;&gt;From modules to a dedicated board&lt;/h2&gt;
&lt;p&gt;The first builds answered one question: could I recreate this illusion with fairly simple, modern electronics? Once that worked, another question followed: how could I make something reproducible without rebuilding the whole assembly by hand each time?&lt;/p&gt;
&lt;p&gt;The PCB did not emerge from a single drawing. The design went through several revisions, from A1 to A7. An early correction in A1 involved the JST connector polarity: a tiny detail on a schematic, and an essential one on the real board. Later work was as much about fit as electronics, placing connectors and buttons where they would remain accessible through the enclosure and arranging the components within the available space.&lt;/p&gt;
&lt;p&gt;The clearest change came with &lt;strong&gt;A7, prepared on September 13: components on both sides&lt;/strong&gt;. The board shrank from A5&amp;rsquo;s 32 × 120 mm to &lt;strong&gt;32 × 85 mm&lt;/strong&gt;, roughly 29% less area. It uses four layers and is 1 mm thick. Those millimetres matter when the whole point is to hold the object and tilt it in your hand.&lt;/p&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-one-of-the-boards-received-viewed-from-the-radio-module-side-dimensions-in-the-text-refer-to-the-documented-a7-pcb-rather-than-measurements-taken-from-this-photograph&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;An assembled green circuit board on a wooden table, with a radio module, its antenna, and a white connector&#34; srcset=&#34;
               /en/post/esp32-rolling-stone-pcb/featured_hu_f48e6955f4999a5a.webp 400w,
               /en/post/esp32-rolling-stone-pcb/featured_hu_49b1f33a863db3f6.webp 760w,
               /en/post/esp32-rolling-stone-pcb/featured_hu_8f0bdf2ef7efc8cb.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/esp32-rolling-stone-pcb/featured_hu_f48e6955f4999a5a.webp&#34;
               width=&#34;572&#34;
               height=&#34;760&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      One of the boards received, viewed from the radio-module side. Dimensions in the text refer to the documented A7 PCB, rather than measurements taken from this photograph.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;ordering-an-assembly-not-just-copper&#34;&gt;Ordering an assembly, not just copper&lt;/h2&gt;
&lt;p&gt;I ordered the boards from &lt;strong&gt;JLCPCB&lt;/strong&gt;. That stage needs more than a circuit-board file: the Gerbers, bill of materials, and placement files all have to describe exactly the same assembly.&lt;/p&gt;
&lt;p&gt;The A7 export specified &lt;strong&gt;89 assembled components&lt;/strong&gt;, with &lt;strong&gt;52 on the top and 37 on the bottom&lt;/strong&gt;, across 37 BOM lines. The complete design contained 103 footprints, which is a different count from the components included in the assembly order.&lt;/p&gt;
&lt;p&gt;Before that export, the electrical and design-rule checks reported zero errors, with no unrouted connections. But automated checks do not tell the whole story. Reviewing the JLCPCB assembly preview on September 17 revealed a rotation issue: &lt;strong&gt;U9&amp;rsquo;s leads appeared at 90 degrees to the pads&lt;/strong&gt;. U5 and the four MAX chips also needed pin-number checks. I had to examine how the manufacturer interpreted the placement file, not just whether the PCB was correctly routed.&lt;/p&gt;
&lt;p&gt;That is a useful lesson from this order: keep the schematic, board, and actual submitted files together, and inspect the assembly preview. The placement file is as much a part of the hardware as the copper.&lt;/p&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-another-view-of-the-boards-received-with-the-usb-c-port-and-buttons-accessible-after-the-manufacturing-files-there-is-finally-hardware-to-try&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;An assembled board photographed diagonally, showing the USB-C port, two pushbuttons, and components along the centre&#34; srcset=&#34;
               /en/post/esp32-rolling-stone-pcb/pcb-usb_hu_a57e7d79b543f8b2.webp 400w,
               /en/post/esp32-rolling-stone-pcb/pcb-usb_hu_9842b14f5a2bb380.webp 760w,
               /en/post/esp32-rolling-stone-pcb/pcb-usb_hu_ed6cb61702c7b9ba.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/esp32-rolling-stone-pcb/pcb-usb_hu_a57e7d79b543f8b2.webp&#34;
               width=&#34;572&#34;
               height=&#34;760&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      Another view of the boards received, with the USB-C port and buttons accessible. After the manufacturing files, there is finally hardware to try.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;back-on-the-bench-actual-results&#34;&gt;Back on the bench: actual results&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;October 9&lt;/strong&gt; tests brought A7 through flashing and into operation. Telemetry showed the physics loop running between &lt;strong&gt;1,999 and 2,000 Hz&lt;/strong&gt;, with IMU readings at approximately &lt;strong&gt;1,733 Hz&lt;/strong&gt;. The simulation now runs at about 2 kHz, compared with the 1 kHz loop in the earlier builds described on this blog.&lt;/p&gt;
&lt;p&gt;But getting the firmware running also exposed a hardware weakness: &lt;strong&gt;I had been too optimistic about the power supply design&lt;/strong&gt;. The board experienced brownouts: the supply voltage fell low enough for the ESP32 to reset. A device that restarts can soon look healthy again, so simply seeing the simulation running was not enough. I needed a way to tell whether a test had introduced another power-related reset, even if I had missed it happening.&lt;/p&gt;
&lt;p&gt;That led to a small persistent diagnostic in the A7 firmware. At startup, it reads the ESP32&amp;rsquo;s reset reason with &lt;code&gt;esp_reset_reason()&lt;/code&gt;. Every boot increments a boot counter; only &lt;code&gt;ESP_RST_BROWNOUT&lt;/code&gt; increments the brownout counter. Both are saved in non-volatile storage through &lt;code&gt;Preferences&lt;/code&gt;, so a restart does not erase the evidence.&lt;/p&gt;
&lt;p&gt;The firmware prints the totals over serial, exposes the brownout count in its status output, and flashes the LED red three times after a brownout reset. That gives me both an immediate signal on the device and a record to compare before and after an experiment. It counts resets attributed to brownouts by the chip, rather than measuring every voltage dip.&lt;/p&gt;
&lt;p&gt;With that diagnostic in place, the later checks were easier to interpret: the brownout counter stayed at &lt;strong&gt;9&lt;/strong&gt;, with no new brownout resets recorded during that run, while the audio-drop counter stayed at &lt;strong&gt;zero&lt;/strong&gt;. That was encouraging within the tested conditions. It did not establish that the underlying power-supply limitation was resolved; it gave us a way to track the problem while working out where the design needed more margin.&lt;/p&gt;
&lt;h2 id=&#34;letting-the-imu-measure-the-actuators&#34;&gt;Letting the IMU measure the actuators&lt;/h2&gt;
&lt;p&gt;The PCB was designed from the outset with &lt;strong&gt;four independently driven channels&lt;/strong&gt;, to accommodate the full Drake range: &lt;strong&gt;LFi, LF, MF and HF&lt;/strong&gt;. The aim was to combine their different strengths for a broader usable frequency range, more output where needed, and more flexibility in the effects we could render. Measuring their response would tell us how to distribute the signal to make use of that potential, within the available power budget.&lt;/p&gt;
&lt;p&gt;That architecture also leaves room for different builds. The &lt;strong&gt;same PCB can support versions with one, two, three or four actuators&lt;/strong&gt;, populating only the amplifier chips and associated components needed for the chosen channels. A simpler version would not need a new board layout or all four amplifier circuits assembled. The two-actuator prototype is one configuration of that platform.&lt;/p&gt;
&lt;p&gt;For these first measurements, &lt;strong&gt;LFi and HF&lt;/strong&gt; were fitted. The TITAN Drake datasheet gave us the starting point: an impact-oriented LFi and a higher-frequency HF, with nominal peak-acceleration frequencies of 65 and 160 Hz under the manufacturer&amp;rsquo;s 100 g test conditions. That suggested complementary roles, but did not tell us their response in this assembly. The immediate task was to characterize this pair; the same approach could then guide other combinations on the four-channel board.&lt;/p&gt;
&lt;p&gt;The useful trick was already sitting on the PCB: &lt;strong&gt;the IMU used to measure the tilt could also measure the vibrations we generated&lt;/strong&gt;. In a dedicated bring-up mode, the firmware drove one actuator at a time through 40 frequencies from 20 to 500 Hz, recorded a silent baseline, and measured acceleration on all three axes. It picked out the response at the driven frequency using the actual sample timestamps—a lock-in measurement—rather than treating every movement of the board as useful output. It also examined harmonics where the sampling rate allowed it, then drove the pair with matching and opposite polarities to see how their vibrations combined.&lt;/p&gt;
&lt;p&gt;This was still a &lt;strong&gt;proof of concept, with the actuators held in place by zip ties&lt;/strong&gt;, rather than a finished mechanical assembly. That improvised mounting helps explain why the curves are not particularly clean: the IMU sees the actuators through the fixings and the mechanical path to the sensor. The useful result at this stage was showing that we could measure and compare their responses with the electronics already on the board.&lt;/p&gt;
&lt;p&gt;In that setup, the October 8 sweep at 0.25 full-scale drive put the measured LFi peak near &lt;strong&gt;69 Hz&lt;/strong&gt;, and the HF peak near &lt;strong&gt;238 Hz&lt;/strong&gt;. These are observations from this temporary assembly, not new specifications for the bare actuators or a controlled comparison with the datasheet. They give us an initial view of how the pair behaves together. A better mechanical assembly, followed by another sweep, is needed before using those curves as a firm basis for tuning.&lt;/p&gt;
&lt;p&gt;















&lt;figure  id=&#34;figure-october-8-proof-of-concept-sweep-20500-hz-025-full-scale-drive-per-active-channel-the-actuators-were-held-by-zip-ties-the-uneven-curves-include-that-temporary-mounting-these-measurements-demonstrate-the-method-and-will-need-repeating-with-a-better-assembly&#34;&gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;Measured actuator sensitivity, distortion, combined response and relative phase from the onboard IMU&#34; srcset=&#34;
               /en/post/esp32-rolling-stone-pcb/actuator-response_hu_f5791eee1c3f06ba.webp 400w,
               /en/post/esp32-rolling-stone-pcb/actuator-response_hu_1b1683a00ae9b2e8.webp 760w,
               /en/post/esp32-rolling-stone-pcb/actuator-response_hu_d578539217a67d4e.webp 1200w&#34;
               src=&#34;https://antoine.weill-duflos.fr/en/post/esp32-rolling-stone-pcb/actuator-response_hu_f5791eee1c3f06ba.webp&#34;
               width=&#34;760&#34;
               height=&#34;497&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;figcaption&gt;
      October 8 proof-of-concept sweep, 20–500 Hz, 0.25 full-scale drive per active channel. The actuators were held by zip ties; the uneven curves include that temporary mounting. These measurements demonstrate the method and will need repeating with a better assembly.
    &lt;/figcaption&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The analysis also explored a crossover: splitting a desired signal between the two actuators while accounting for their sensitivity, how they add together, and the available drive headroom. It recommended a 330 Hz crossover for that run. With this temporary mounting, that is an exploratory setting to revisit after rebuilding and measuring again. Only LFi and HF were fitted; the other two amplifier channels remained unused.&lt;/p&gt;
&lt;h2 id=&#34;why-the-rolling-stone-needed-a-texture-mode&#34;&gt;Why the rolling stone needed a texture mode&lt;/h2&gt;
&lt;p&gt;Once the board worked, the question changed from “does it vibrate?” to “does it feel like a ball?” The classic rolling waveform conveyed motion, but its repeated shape lacked the finer, higher-frequency detail I expected from a metal ball moving inside a plastic tube. Turning up the gain would make that same limited signal stronger. It would not add the missing texture—and the power-supply trouble was another reason not to reach for amplitude first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TEXTURED keeps the rolling physics and changes how that motion becomes vibration.&lt;/strong&gt; Instead of repeating only the original waveform, it moves the virtual ball over a spatial roughness profile and uses that excitation to drive damped resonances. Linking roughness to distance travelled makes the pattern follow the ball&amp;rsquo;s motion: changing its speed changes how quickly it encounters those details. The LFi carries the low-frequency body and impacts; the HF adds the finer layer. Classic rolling remains available for direct comparison.&lt;/p&gt;
&lt;p&gt;On A7, body resonances at 90, 280 and 430 Hz are supplemented by detail generated at 700, 1,800 and 3,600 Hz in the 48 kHz audio path. These last numbers describe the &lt;strong&gt;generated signal&lt;/strong&gt;: our actuator sweep stopped at 500 Hz, so it did not establish how much of those higher bands reaches the hand. I liked the resulting TEXTURED sensation, but separating a promising perceptual result from a measured mechanical response gives the next experiments a clear purpose.&lt;/p&gt;
&lt;h2 id=&#34;why-keep-measuringand-why-turn-it-into-a-game&#34;&gt;Why keep measuring—and why turn it into a game?&lt;/h2&gt;
&lt;p&gt;The &lt;strong&gt;Tauri companion connected over USB&lt;/strong&gt; makes the iteration easier to interpret. Seeing the simulated ball while feeling it helps separate a wrong motion model from a poor vibration rendering. Mode and gain controls make comparisons quicker, while diagnostics let me check whether a change in sensation coincides with a timing or reset problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MARBLES&lt;/strong&gt; asks a different question: can the vibrations convey what is inside without showing it? The intended game is to shake the device like a matchbox and guess how many balls it contains. Hidden rounds use zero to five identical virtual 10 mm metal balls, with the count and positions concealed until reveal. Wall impacts and collisions between balls become clues. It gives the simulation a purpose beyond watching an animation: finding out whether the contact events are distinct enough to interpret through the hand.&lt;/p&gt;
&lt;p&gt;That is also why the remaining work matters. More response measurements would tell us which synthesized details actually survive the actuators and mounting, so we can shape the signal rather than spend power on ineffective output. More supply margin is needed to preserve convincing impacts without triggering resets. The enclosure and grip need attention because they are part of the vibration path to the hand. Finally, repeatable comparisons—including gentle rolling, which initially felt too muted—will help distinguish “more vibration” from a more convincing ball. The PCB works; now it gives us a platform for asking those better questions.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;../../project/esp32-rolling-stone/&#34;&gt;project page&lt;/a&gt; brings the series together. The &lt;a href=&#34;https://github.com/Leicas/esp32-ball&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;public ESP32 Ball repository&lt;/a&gt; contains the firmware and companion application for the earlier builds.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
