<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://positron96.gitlab.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://positron96.gitlab.io/" rel="alternate" type="text/html" /><updated>2026-08-16T19:38:39+00:00</updated><id>https://positron96.gitlab.io/feed.xml</id><title type="html">Paul’s DIY blog</title><subtitle>A blog about DIY projects, particularly railroad modelling.</subtitle><author><name>Paul Melnikov</name></author><entry><title type="html">Reviving DCC command Station</title><link href="https://positron96.gitlab.io/2026/07/13/cs-update.html" rel="alternate" type="text/html" title="Reviving DCC command Station" /><published>2026-07-13T00:00:00+00:00</published><updated>2026-07-13T17:16:21+00:00</updated><id>https://positron96.gitlab.io/2026/07/13/cs-update</id><content type="html" xml:base="https://positron96.gitlab.io/2026/07/13/cs-update.html"><![CDATA[<div class="paragraph">
<p>After several years of pause,
  I&#8217;ve decided to update my <a href="https://github.com/positron96/LocoNetControlStation">LocoNetControlStation project</a>,
  both hardware and software side.</p>
</div>
<div class="paragraph">
<p>Hardware changes in new version:</p>
</div>
<figure class="flexfig large">
  <a href="pic-pcb.webp">
  <img src="pic-pcb.webp" ></a>

  <a href="pic-din-case.webp" title="DIN rail case, from AliExpress">
  <img src="pic-din-case.webp" ></a>
</figure>
<div class="ulist">
<ul>
<li>
<p>Fit the Command station into a DIN rail enclosure.</p>
</li>
<li>
<p>Update DCC circuitry to modern ICs (instead of old L298N) to ease reading of current.</p>
</li>
<li>
<p>Use official ESP32-DevKitC board instead of Lolin32 Lite to avoid problems with availability and quality.</p>
</li>
<li>
<p>Modularize the design to allow adding new features without PCB redesign, for exmaple LCC or RailCom</p>
</li>
<li>
<p>Use USB-PD to power the board, use switching regulator instead of LM7805.</p>
</li>
<li>
<p>Add a small OLED display for status and diagnostics.</p>
</li>
<li>
<p>Limit current of LocoNet RailSync to better follow specs (to simplify things, it&#8217;s limited to 30mA, roughly 10 times less then the documentation mentions).</p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The PCB design will be released to public when finished,
but I would consider it as an educational project for other people,
  rather than useful for recreating.
I adapted it for my capabilities and needs, e.g. used components that I had in stock,
  will use full-color PCB because it&#8217;s cheaper with JLCPCB coupons,
  so it might not be the optimal to replicate 1-to-1.
Same applies to firmware.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Software changes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Actualize toolchains, update ESP32 SDK, libraries.
The project was last actively worked on in 2021, so everything is rather encient.
I was surprised that it still compiles, though.</p>
</li>
<li>
<p>Regularly send (refresh) function states to locomotives (old code only sends loco speed/direction packets, this was an issue I noticed while running on dirty tracks).</p>
</li>
<li>
<p>Display diagnostic info on OLED display (it shows number of WiThrottle/LbServer clients, track power state, number of running trains and some other)</p>
</li>
<li>
<p>Fast clock support on LocoNet, WiThrottle (and, in future, DCC)</p>
</li>
<li>
<p>Better processing of LocoNet turnout commands (also fixed some bugs with LocoNet slot ownership and dispatching)</p>
</li>
<li>
<p>WiThrottle has support for "steal" messages.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Upgrading code to ESP-IDF v5 proved to be a major challenge.
New timer API caused the DCC bit timings to break, as the jitter in timer callbacks was too large in the new API for some reason.
I was able to somewhat combat this by switching to RMT peripheral, but it&#8217;s also suffering from problems due to delays between RMT transmissions.
In new SDK RMT peripheral has completely new API which <a href="https://github.com/espressif/esp-idf/issues/13003">doesn&#8217;t allow</a> continous streaming.
So, a legacy RMT driver was used for uninterrupted streaming.
Because it&#8217;s completely removed in ESP-IDF 6, I decided to copy it from SDK 5 and store it as a library in repository
  (project still uses SDK 5 though).
The implementation has limitations on DCC packet size, it&#8217;s limited to allocated RMT memory.
ESP32 has 64 symbols (=DCC bits) per block, of which it it has 8,
  so it&#8217;s not a problem for original ESP32, but can be a major limitation for newer ESP32s.</p>
</div>
<div class="paragraph">
<p>Another major task was refreshing of function packets on DCC track.
This required inventing some kind of a priority queue backed by table of alocated locomotives so that
  each locomotive regularly produces a speed/dir DCC packet or a function packet
  (3 groups of functions are cycled through, totalling 12 functions).
Other, non-locomotive packets go through the queue directly and get picked up by DCC pulse generator
  according to their priority.
For now priority system is rather simple, stop and emergency stop packets have higher priority than normal packets.</p>
</div>
<div class="paragraph">
<p>A lot of other work was done, I&#8217;ve spent a month in total on the software, I think.
There are still some major improvements possible,
  like handling of various messages via a application-wide message bus
  and processing physical LocoNet packets in a separate task (to not block other tasks that initiate communication).</p>
</div>
<div class="paragraph">
<p>PS. While I was updating the PCB, easyEDA released a version 3 and the release process disappointed me a lot.
Not only was the new version lacking features from EasyEDA v2 for no reason,
it&#8217;s a major incompatible release, its v3 file format is incompatible with v2 software,
  so everyone needs to upgrade the projects, and the process is irreversible.
Previous version was pulled from the website and is not available in browser,
  so users are forced to use the new one
  even if the new feature set is limiting for them.
In addition,
To add to the insult, support is ignoring feedback and giving responses like "The v3 effect has already been changed and will not be retracted based on a minority of opinions."</p>
</div>
<div class="paragraph">
<p>All in all, very frustrating experience.
I will consider KiCAD in future.</p>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="railway" /><category term="accessories" /><category term="electronics" /><category term="arduino" /><category term="esp32" /><category term="dcc" /><summary type="html"><![CDATA[After several years of pause, I&#8217;ve decided to update my LocoNetControlStation project, both hardware and software side.]]></summary></entry><entry><title type="html">Making scale lumber loads out of reed</title><link href="https://positron96.gitlab.io/2026/07/13/lumber.html" rel="alternate" type="text/html" title="Making scale lumber loads out of reed" /><published>2026-07-13T00:00:00+00:00</published><updated>2026-07-13T15:36:29+00:00</updated><id>https://positron96.gitlab.io/2026/07/13/lumber</id><content type="html" xml:base="https://positron96.gitlab.io/2026/07/13/lumber.html"><![CDATA[<figure class="flexfig large">
  <a href="ph-1.webp">
  <img src="ph-1.webp" ></a>
</figure>
<div class="paragraph">
<p>I decided to make a load for a log car
  that has been standing empty for a long time,
  waiting to be used for some purpose.
The result turned out to look very realistic, if I can say so myself.</p>
</div>
<div class="paragraph">
<p>At first I had the idea of making a 3D model of a log pile and printing it,
  but then I decided that a model made from natural products would look better
  and take less time.</p>
</div>
<div class="paragraph">
<p>So, the creation process looked like this:
  I gathered dry reed outside,
  cut it into pieces of the required length,
  stuffed the ends with wood putty,
  smeared the tree trunks with it to have some rough texture,
  glued the logs together to form loads and piles,
  and painted them with acrylic paints.</p>
</div>
<div class="paragraph">
<p>Glueing first and painting later saved a lot of time, as otherwise I would need to do a lot more painting.</p>
</div>
<div class="paragraph">
<p>The trunks were painted with a mixture of
  Vallejo Burnt Umber and Vallejo Orange in various proportions.</p>
</div>
<div class="paragraph">
<p>The most tedious part turned out to be cutting all the trunks to required length so that the load fits into the wagon but is not too short.</p>
</div>
<div class="paragraph">
<p>The most difficult part however was making proper color for the cuts;
  I even had to repaint them a couple of times, because they looked
  either too bright, too dark, or too yellow.
In the end I can&#8217;t even say exactly what mixture was used: something like
  "a lot of yellow, a bit of rust, a whole lot of water."</p>
</div>
<figure class="flexfig">
  <a href="ph-step0.webp" title="Future lumber in natural habitat">
  <img src="ph-step0.th.webp" ></a>
  <a href="ph-step1.webp" title="Chopped reed stems">
  <img src="ph-step1.webp"></a>
  <a href="ph-step2.webp" title="A long process of trimming the length so that everything fits">
  <img src="ph-step2.webp"></a>
  <a href="ph-step3.webp" title="Assembled pile">
  <img src="ph-step3.webp"></a>
  <a href="ph-step4.webp" title="Covering sticks with wood putty">
  <img src="ph-step4.webp"></a>
  <a href="ph-step5.webp" title="Glueing sticks and painting">
  <img src="ph-step5.webp"></a>
  <figcaption>Photos of the process</figcaption>
</figure>]]></content><author><name>Paul Melnikov</name></author><category term="railway" /><category term="accessories" /><category term="ho-scale" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Arduino libraries for advanced audio playback</title><link href="https://positron96.gitlab.io/2026/05/18/audio-libraries.html" rel="alternate" type="text/html" title="Arduino libraries for advanced audio playback" /><published>2026-05-18T00:00:00+00:00</published><updated>2026-08-16T19:37:31+00:00</updated><id>https://positron96.gitlab.io/2026/05/18/audio-libraries</id><content type="html" xml:base="https://positron96.gitlab.io/2026/05/18/audio-libraries.html"><![CDATA[<div class="paragraph">
<p>This is a follow-up to my <a href="/2023/07/31/on-advanced-audio">old post</a>
  about advanced audio effects on a diorama,
  where I described the capabilities of the ESP8266Audio library
  and how it can be used to create realistic sound effects.</p>
</div>
<div class="paragraph">
<p>I decided to have my own try on welding effect on a model train layout with sounds,
  and here I present my findings on the topic of audio libraries for audio playback.</p>
</div>
<div class="paragraph">
<p>I&#8217;ve found some more Arduino libraries that allow such tasks.
Compared to ESP8266Audio, some of these solutions target AVR MCUs,
  so will work on a classic Arduino UNO or NANO.</p>
</div>
<div class="sect1">
<h2 id="mozzi"><a href="https://github.com/sensorium/Mozzi">Mozzi</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>The library is aimed at music synthesis, so polyphony comes as a default,
  as are some effects like frequency changes.
Has built-in support for looping samples, with customizable loop points,
  which is a nice feature for engine sounds or similar long-lasting looping sounds.</p>
</div>
<div class="paragraph">
<p>Does not support WAV files,
  you&#8217;ll need to encode your samples as a Mozzi-specific C array.
It&#8217;s designed to play small samples that are stored in MCU flash,
  so completely lacks features for streaming data from SD card, Internet or anything similar.</p>
</div>
<div class="paragraph">
<p>Targets AVR-based Arduinos, so can work with minimal amount of resources.
  Also supports a wide range or targets like STM32, RP2xxx, ESP32, ESP8266, Teensy and others.</p>
</div>
<div class="paragraph">
<p>The API allows to start/stop individual samples at any time,
  so it&#8217;s easy to play multiple samples at the same time and synchronize sounds with other events,
  like lighting effects.
All in all, I quite liked the API and structure of the library.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="tmrpcm"><a href="https://github.com/TMRh20/TMRpcm">TMRpcm</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Plays WAV files from SD card (attached to Arduino via SPI bus).
It&#8217;s written to play one file at a time,
  but can be used to play 2 files simultaneously
  by sending them to different PWM channels and mixing them in hardware
  (see MultiTrack examples).
Works with AVR-based Arduinos, so needs minimal amount of resources.</p>
</div>
<div class="paragraph">
<p>I briefly looked at the internals of the library and <del>it's horrible</del>
  didn&#8217;t like the design decisions,
  for example those that restrict playing multiple files into a single output.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="esp32synth"><a href="https://github.com/danilogcrf2-oss/ESP32Synth">ESP32Synth</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>As the name suggests, works only with ESP32-based MCUs
  (and relies on its FreeRTOS for background processing).
Has massive polyphony, can play samples from SPI SD card.
Can output to I2S DACs, built-in DACs, PWM/PDM pins, Bluetooth sinks.
I haven&#8217;t used it, as for this usecase it doesn&#8217;t add much compared to the ESP8266Audio library.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="backgroundaudio"><a href="https://github.com/earlephilhower/BackgroundAudio">BackgroundAudio</a></h2>
<div class="sectionbody">
<div class="paragraph">
<p>Successor to the ESP8266Audio library, with limited feature set but better performance.
Only supports ESP32 and RP2xxx MCUs, not AVR-based Arduinos.
I haven&#8217;t used it, but may try in future.</p>
</div>
</div>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="electronics" /><category term="audio" /><category term="arduino" /><category term="esp8266" /><category term="scenery" /><summary type="html"><![CDATA[Making realistic continuous and polyphonic sound effects]]></summary></entry><entry><title type="html">On supercapacitor Stay-alive circuits</title><link href="https://positron96.gitlab.io/2026/05/07/stay-alive.html" rel="alternate" type="text/html" title="On supercapacitor Stay-alive circuits" /><published>2026-05-07T00:00:00+00:00</published><updated>2026-05-07T15:41:13+00:00</updated><id>https://positron96.gitlab.io/2026/05/07/stay-alive</id><content type="html" xml:base="https://positron96.gitlab.io/2026/05/07/stay-alive.html"><![CDATA[<div class="paragraph">
<p>Dirty tracks and power interruptions are a bane of model railroads.
To combat this, stay-alive circuits are used, which usually consist of a bulky capacitor and
  some charge-discharge circuitry.
Electrolytic capacitors of several 1000s of uF (micro Farads) are typically used.</p>
</div>
<div class="paragraph">
<p>In recent years, supercapacitors are becoming more and more popular.
These state-of-the art devices with capacitances of several Farads(!)
 allow several seconds and several dozen centimiters of travel when power is interrupted.</p>
</div>
<div class="paragraph">
<p>The complications with supercapacitors come from the fact that
 they are usually low-voltage devices, 2.7-5.4V (5.4V are typically just 2 2.7V caps in series internally).
Another issue with capacitors is that when empty, they take very high current,
  which to the command station can look as a short-circuit or an overcurrent situation,
  especially if there are a lot of locomotives on tracks and they all start to
  charge at the same time (which happens when power is turned on).</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
To regulate the second issue, RailCommunity standard RCN-530 requires that charging current be limited to 100mA.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>So, the usual solution with supercapacitors is to charge them to their nominal voltage,
  and then to raise voltage back when discharging.
First part is done with either a linear regulator or a step-down switching regulator,
  second part is performed by a step-up switching regulator.</p>
</div>
<div class="paragraph">
<p>For quite some time I was looking for examples of supercapacitor-based circuits, and finally found
  an open source design here:
  <a href="https://www.stummiforum.de/t171549f21-RE-SuperCapLader-im-Eigenbau-Goldcaps-als-Pufferspeicher.html" class="bare">https://www.stummiforum.de/t171549f21-RE-SuperCapLader-im-Eigenbau-Goldcaps-als-Pufferspeicher.html</a>
  (in German, and access to uploaded files requires an account)
In fact, the forum thread contains several generations with different features.</p>
</div>
<div class="paragraph">
<p>All designs from original poster (schumo99) use
  a Diodes Inc. AP3211 step-down (buck) regulator to drop input to charging voltage,
  and an Olimex MT3608 step-up (boost) regulator for raise it back to 10V.
Both regulators need their own inductors, one of which is the biggest component on the PCB.</p>
</div>
<div class="paragraph">
<p>Step-down regulator has an enable pin that is controlled by a 10V Zenner diode,
  it&#8217;s designed to enable charging when input voltage is above ~11.5V.
Step-up regulator is always enabled, but switches itself off if input voltage is higher than 10V.</p>
</div>
<div class="paragraph">
<p>In the first generation of the design, charge current is limited by a 10-15 Ohm resistor in series with the supercapacitor.
As a result, the resistor wastes a lot of energy at the beginning of charging cycle when the current is high.
Wasted energy mandates that the resistor be big enough to dissipate it.</p>
</div>
<div class="paragraph">
<p>Second design (called "fast") improves on this by replacing current-limiting resistor with
  modified feedback loop for the regulator to limit the current as well as voltage.
This effectively creates a CC/CV (constant current/constant voltage) charging circuit
  often found in Li-Ion chargers.</p>
</div>
<div class="paragraph">
<p>Another important characteristic of supercapacitor designs is minimum capacitor voltage
  that can still be used by boost converter.
For example, when using 2.7V supercapacitor with a boost converter that works from 2.0V,
  only portion of energy from 2.7V to 2V can be used, and the rest will stay in the capacitor.
For this reason, putting 2 2.7V capacitors in series to form a 5.4V capacitor is preferrable
  even though the capacitance of such connection is halved.</p>
</div>
<div class="paragraph">
<p>After studying the whole forum thread, I&#8217;ve come up with my own ideas for improvements.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Ideal solution: bi-directional buck-boost converter.
Such a device replaces both charging and discharging havles of the circuit.
It operates as a buck converter to charge the capacitor, and then operates as a boost converter to discharge it.
Such a device would decrease component count by a lot, e.g. only only one inductor would be needed.
Unfortunately, I could not find any part that fits this usecase perfectly,
these are the ones that come close (but still unsuitable):</p>
<div class="openblock">
<div class="content">
<div class="ulist">
<ul>
<li>
<p>SY9329 - CC/CV DC-DC, needs I2C to configure and switch, not found on LCSC</p>
</li>
<li>
<p>BQ25690 - CC/CV DC-DC, needs 1 mosfet, seems to require I2C to switch</p>
</li>
<li>
<p>TPS61289 - DC-DC, no CC mode, needs external mosfet</p>
</li>
<li>
<p>ISL81601 - CC/CV DC-DC, needs 4 external mosfets</p>
</li>
<li>
<p>LTC3110 - CC/CV DC-DC, 5V input only</p>
</li>
<li>
<p>MAX38889 - DC-DC with CC/CV, only 5V, expensive, otherwise would be perfect</p>
</li>
</ul>
</div>
</div>
</div>
<div class="paragraph">
<p>On top of lack of needed features, all these are rather specialized devices and are somewhat expensive.</p>
</div>
</li>
<li>
<p>CC/CV buck converters.
The described design uses a CV buck converter with a modified feedback loop to acheive CC/CV functionality.
In fact, ready-made CC/CV buck converters exist,
so they can be used instead, reducing component count.
Devices of this nature can be found in several categories like
Switch-mode regulators (are usually CV-only, CC mode is rare), LED drivers (these are CC-mode regulators, and CV mode for them is rare), battery chargers (these are often tailored to specific voltages for specific chemistry),
which complicates searching for them.
Here are some potential devices that I&#8217;ve found, and most have some drawbacks.</p>
<div class="ulist">
<ul>
<li>
<p>TPS92365x - suitable LED driver from TI, voltage is limited by over-voltage-protection feature.</p>
</li>
<li>
<p>BQ24640 - CC/CV charger, proper input voltage, needs external MOSFETs. Comes in 3x3mm package. Might be used, needs testing, but price is not that attractive at ~$3 on LCSC.</p>
</li>
<li>
<p>BQ25306 - CC/CV battery charger, up to 17V (but 28V abs max)</p>
</li>
<li>
<p>LT3663 - CC/CV step-down regulator from LT, expensive, almost missing on LCSC</p>
</li>
<li>
<p>A7431A - CC/CV step-down, big package, not found on LCSC.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Step-up regulators with low startup voltage.
MT3608 used in the described design start up from 2V.
This can be improved by replacing it with a boost converter with a lower startup voltage.
Here I coundn&#8217;t find much, but this chip was suggested <a href="https://github.com/CDFER/NIMRS-21Pin-Decoder/discussions/3#discussioncomment-16400330">here</a>:</p>
<div class="ulist">
<ul>
<li>
<p>ME2149: 0.9V startup</p>
</li>
</ul>
</div>
</li>
</ul>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="electronics" /><category term="railway" /><summary type="html"><![CDATA[Dirty tracks and power interruptions are a bane of model railroads. To combat this, stay-alive circuits are used, which usually consist of a bulky capacitor and some charge-discharge circuitry. Electrolytic capacitors of several 1000s of uF (micro Farads) are typically used.]]></summary></entry><entry><title type="html">Dumpcar and its updates</title><link href="https://positron96.gitlab.io/2026/03/09/dumpcar.html" rel="alternate" type="text/html" title="Dumpcar and its updates" /><published>2026-03-09T00:00:00+00:00</published><updated>2026-03-09T16:05:35+00:00</updated><id>https://positron96.gitlab.io/2026/03/09/dumpcar</id><content type="html" xml:base="https://positron96.gitlab.io/2026/03/09/dumpcar.html"><![CDATA[<div class="paragraph">
<p>For a couple months I&#8217;ve been working a new project,
  a model of a dumpcar wagon.
The model needs motorized tipping and mechanized sideboards.</p>
</div>
<div class="paragraph">
<p>For full details, you can go to <a href="/projects/dumpcar/">project page</a>,
  while this post has small update for the project.</p>
</div>
<!-- Courtesy of embedresponsively.com -->

  <div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/jkvstKRyjeE" title="YouTube video player" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowfullscreen></iframe>
  </div>
<div class="paragraph">
<p>This is a video with the latest state of mechanical features.
I&#8217;ve printed both sideboards with linkages,
  and assembled the full bed.
The joints are free to rotate to make motors' work easier later.</p>
</div>
<div class="paragraph">
<p>As I only assembled one side before, it turned out that
  putting 2 sets of linkages into the bed creates a rather tight fit
  (especially after some shrinking and warping of the resin).
So I had to redesign the linkages and their slot to make linkages thinner,
  slot larger,
  while still keeping things as thick as possible to retain rigidity.
I also had to leave more empty space for protruding pieces of copper wire,
  as they turned out to stick out and scratch resin, creating friction and preventing free move.
As a countermeasure I also try to clip them as flush as possible.</p>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="railroad" /><category term="wagon" /><category term="3d-printing" /><category term="mechanics" /><category term="electronics" /><category term="animated" /><category term="motorized" /><category term="ho-scale" /><summary type="html"><![CDATA[For a couple months I&#8217;ve been working a new project, a model of a dumpcar wagon. The model needs motorized tipping and mechanized sideboards.]]></summary></entry><entry><title type="html">LEDs and magnet magic</title><link href="https://positron96.gitlab.io/2026/02/26/leds-and-magnets.html" rel="alternate" type="text/html" title="LEDs and magnet magic" /><published>2026-02-26T00:00:00+00:00</published><updated>2026-02-26T09:38:35+00:00</updated><id>https://positron96.gitlab.io/2026/02/26/leds-and-magnets</id><content type="html" xml:base="https://positron96.gitlab.io/2026/02/26/leds-and-magnets.html"><![CDATA[<!-- Courtesy of embedresponsively.com -->

  <div class="responsive-video-container">
    <iframe src="https://www.youtube-nocookie.com/embed/X56wpxd_bq4" title="YouTube video player" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowfullscreen></iframe>
  </div>
<div class="paragraph">
<p>In 2024 I&#8217;ve made a small model of a construction site light tower and generator.
I forgot to make a post about it here, so here it goes.</p>
</div>
<div class="paragraph">
<p>At first glance it looks like a rather simple scale model, just with fine details.
However, the light tower is functional,
  and has a trick up its sleeve - it only turns on when you "attach" a generator to it.</p>
</div>
<div class="paragraph">
<p>The generator is, in fact, just a magnet,
  and the tower contains all the power and logic.
The power supply is a small Li-Ion battery (from TWS headphones),
  and the "logic" is a reed switch that turns on when the magnet is close.
The size of the magnet is chosen so that it triggers the switch
  when placed on one side of the tower, but on the other.</p>
</div>
<div class="paragraph">
<p>The idea is that these models should be transported by an RC truck across the diorama,
  unloaded on site, and then the operator could turn the lights on,
  all remotely, using only a manipulator crane.</p>
</div>
<div class="paragraph">
<p>Further idea is to use magnetic sensor IC instead of a reed switch,
  for footprint reduction.
The sensors are available in SOT23 package, for example.
You can read more about those in <a href="/2025/10/21/magnet-switches.html">this post</a>.</p>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="pcb" /><category term="electronics" /><category term="1/87 scale" /><category term="magnets" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">A memo about selection of hand-solderable miniaturized electronic components</title><link href="https://positron96.gitlab.io/2026/02/24/ee-miniaturization.html" rel="alternate" type="text/html" title="A memo about selection of hand-solderable miniaturized electronic components" /><published>2026-02-24T00:00:00+00:00</published><updated>2026-02-26T09:38:35+00:00</updated><id>https://positron96.gitlab.io/2026/02/24/ee-miniaturization</id><content type="html" xml:base="https://positron96.gitlab.io/2026/02/24/ee-miniaturization.html"><![CDATA[<div class="paragraph">
<p>Part of my latest project is a custom a DCC decoder
  that needs to fit into frame of a dumpcar.
This means it needs to be much smaller than a standard DCC decoder,
  with required width of mere 6 mm.</p>
</div>
<div class="paragraph">
<p>For this, I performed a search of the smallest electronic components possible, that would still do the job,
  with the requirement that they are also hand-solderable,
  i.e. have legs and are not too small.
And they need to be available at LCSC.
Being available for JLCPCB PCB assembly is a bonus.</p>
</div>
<figure class="flexfig large">
  <a href="pic-footprints.webp">
  <img src="pic-footprints.webp" ></a>
  <figcaption>Comparison of different small footprints (and corresponding devices)</figcaption>
</figure>
<div class="sect1">
<h2 id="linear-regulators">Linear regulators</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Usecase: drop track voltage (12-25V) to power MCU and other logic, i.e. 3.3V or 5V.
For small footprints are are limited to low currect output (&lt;50mA),
  but this should be fine for the usecase.</p>
</div>
<div class="paragraph">
<p>Suggested package: <strong>SC-70-5 aka SOT-353 or SOT323-5</strong>.
It&#8217;s smaller than SOT23 while still being legged and solderable.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>ST&#8217;s <a href="https://www.lcsc.com/product-detail/C2798216.html">ST715C50R</a> - 5V output, 24V, 85mA</p>
</li>
<li>
<p><a href="https://www.lcsc.com/product-detail/C2970205.html">ST715C33R</a> is a 3.3V option. It is comparatively expensive and doesn&#8217;t have a lot of availability (&lt;100 in stock at the moment)</p>
</li>
<li>
<p>TechPublic <a href="https://www.lcsc.com/product-detail/C7202975.html">TPS71550DCKR-TP</a> - 5V output, 24V input, 50mA current capacity.</p>
</li>
<li>
<p><a href="https://www.lcsc.com/product-detail/C7202974.html">TPS71533DCKR-TP</a> - 3.3V variant, 24V, 50mA.
Judging by specs and product number, these are a relatives to ST&#8217;s part.
They are noticable cheaper and are easily available.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In my decoder I used TechPublic ones.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="dual-transistors">Dual transistors</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Usecasae: control several high-power outputs with an MCU.
For example, to have standatized decoder outputs for lamps, couplers, smoke machines etc.</p>
</div>
<div class="paragraph">
<p>Package: <strong>SOT-363 aka SC-70-6</strong>.
Same size as SOT-353 before, but with 6 legs.</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.lcsc.com/product-detail/C28739.html">AO7800</a>. 900mA, Vds=20V. These are values from Alpha&amp;Omega, the device is available from many manufacturers.</p>
</li>
<li>
<p><a href="https://www.lcsc.com/product-detail/C48543207.html">NX3008NBKS-TP</a>. 800mA, Vds=30V, works on 3.3V.</p>
</li>
<li>
<p><a href="https://www.lcsc.com/product-detail/C3040316.html">NTJD4001</a> from VBSemi. 2.6A Vds=20V. Same device from other manufacturers offer much smaller currents.</p>
</li>
<li>
<p>BJTs could be also useful, for example, if control voltage is not logic level, but full supply voltage, which might be outside allowable mosfet gate voltages. Seen in <a href="https://www.reddit.com/r/PrintedCircuitBoard/comments/1kl505h/review_request_model_train_control_board_dcc/">this project</a>.
It uses MMDT3904 in SOT-363 (200mA), available from a lot of manufacturers.
MMDT2222 should also work and is seemingly better suited due to higher current capacity.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="diodes">Diodes</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Usecase: rectify DCC track voltage.
Secondary usecase: to feed DCC signal to MCU (as part of a voltage conversion circuit).</p>
</div>
<div class="paragraph">
<p>Package: <strong>SOD-523</strong> (SOD stands for Small Outline Diode).
It is comparable to 0603 is size.
There are 0603 (and 0805) diodes, but they have solder pads only at bottom (as compared to resistors and capacitors that have all sides as leads),
  so not solderable with an iron.</p>
</div>
<div class="paragraph">
<p>To build a rectifier,
  4 of these diodes use less space than a single-chip rectifier.
Smallest full recifier I found is in MBS package (~5x8mm footprint)</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://www.lcsc.com/product-detail/C5310950.html">B5819WT</a> Shottky diode, 40V, 1A, 610mV@1A.
Many options are available by this name, with different characteristics.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Next diode size is SOD-323.
It&#8217;s slightly larger.</p>
</div>
</div>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="electronics" /><summary type="html"><![CDATA[that use usefull for railway modelling and model making]]></summary></entry><entry><title type="html">Ordering metal 3D prints for the 1st (and 2nd) time</title><link href="https://positron96.gitlab.io/2026/02/24/metal-printing.html" rel="alternate" type="text/html" title="Ordering metal 3D prints for the 1st (and 2nd) time" /><published>2026-02-24T00:00:00+00:00</published><updated>2026-02-24T16:42:18+00:00</updated><id>https://positron96.gitlab.io/2026/02/24/metal-printing</id><content type="html" xml:base="https://positron96.gitlab.io/2026/02/24/metal-printing.html"><![CDATA[<div class="paragraph">
<p>JLCPCB&#8217;s 3D printing services offer metal 3D printing, which I wanted to try for some time.
Since I got a coupon for it, I finally made an order.
The model I wanted to print is a frame for <a href="/projects/rc-awd/">a 1/87 scale truck</a>.
The model would benefit from extra weight and of course,
  compared to resin, metal frame is much more durable.</p>
</div>
<div class="sect1">
<h2 id="requirements-and-review-process">Requirements and review process</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There are 2 metal printing processes offered by JLC3DP,
  SLM (selective laser melting) and BJ (binder jetting).
The materials available are titanium and 316 steel.</p>
</div>
<div class="paragraph">
<p>BJ is a bit cheaper, but, as JLC technicians told me,
  is not suitable for such small and detailed models, so I switched to SLM.</p>
</div>
<div class="quoteblock">
<blockquote>
<div class="paragraph">
<p>Please kindly note that this model structure is not suitable for printing BJ-316 material, which is prone to breakage. It is recommended to switch to SLM process.</p>
</div>
</blockquote>
</div>
<div class="paragraph">
<p>For metal SLM printing, the features of the model shall not be smaller than 1.5mm, 2mm preferrable, and the online viewer highlights the parts that are smaller/thinner (or at least it used to before, I don&#8217;t see it now for some reason).
My model is full of features that are much finer,
  so during the review I got a request to
  accept possible risks that the model will come out imperfect.</p>
</div>
<figure class="flexfig">
  <a href="scr-confirm.webp">
  <img src="scr-confirm.webp" ></a>
  <a href="pic-review-warnings.webp">
  <img src="pic-review-warnings.webp"></a>
  <figcaption></figcaption>
</figure>
</div>
</div>
<div class="sect1">
<h2 id="costs-and-duration">Costs and duration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>3D printing of this model costs around $8.
Economy shipping discount covers 3DP orders too,
  so shipping can cost around $3 if the model is light enough.
Around $3 is added on top of this as taxes and duties.</p>
</div>
<div class="paragraph">
<p>Stated manufacturing duration is 3 working days (72h), but in my case it took around 10.
Interestingly, around 7 days were spent in QC step,
  and steps to actually print the model took promised 3 days.
Seems QC was the bottleneck at the moment.</p>
</div>
<div class="paragraph">
<p>The package arrived in the same blue JLCPCB box delivered by same shipping company, as PCBs.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="review">Review</h2>
<div class="sectionbody">
<figure class="flexfig">
  <a href="ph-1.webp">
  <img src="ph-1.webp" ></a>
  <a href="ph-2.webp">
  <img src="ph-2.webp"></a>
  <figcaption></figcaption>
</figure>
<div class="paragraph">
<p>The WOW effect is definitely there!
It is immediately clear that this is a metal part,
  with noticeable weight and strength.
No doubt that it can handle everything that a scale model truck can load it with, and much more.</p>
</div>
<div class="paragraph">
<p>However, cool factor, weight and strength are nearly the only advantages over resin printing.</p>
</div>
<div class="paragraph">
<p>Surface quality and detail representation is significantly worse then for resin 3D print.
This is expected, but still disappointing.
The surface is very rough.</p>
</div>
<div class="paragraph">
<p>Geometrically, the print is not very true to the model
Holes came out smaller than designed;
my typical 1.1mm hole was not large enough for an M1 screw.
Out of 2 gaps of 0.3mm, one was completely jammed with metal bits,
  another was ok.</p>
</div>
<div class="paragraph">
<p>It&#8217;s clear that much looser tolerances must be designed in for metal printing,
  compared to resin printing.
In general, all the features are 0.1&#8212;&#8203;0.2mm larger,
  so this must be compensated in the model.</p>
</div>
<div class="paragraph">
<p>Some protruding parts were warped or bent.
Luckily, this was easily fixed by bending them back with pliers and vise
  (which is in stark contrast to resin prints).</p>
</div>
<div class="paragraph">
<p>316 steel is rather difficult to work with.
I broke nearly all my 1mm drillbits while trying to enlarge the holes.
(but then, they were PCB-orientd drillbits, not intended for any steel, let alone 316 grade).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="second-order">Second order</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Because I was gifted with a coupon for 3D printing,
  I decided to order the model again,
  after making sure that the holes are bigger and tolerances looser.
This time manufacturing went much faster, around 3 days as promised.</p>
</div>
<div class="paragraph">
<p>This time the coupon did not stack with economy shipping offer,
  so in total the order ended up costing more than the first one
  (but still cheap for what it offers).
Seems this is the new change in 2026, as there was an announcement
  that coupons now can cover shipping costs (they didn&#8217;t before),
  and seemingly as a result, the ability to use economy shipping discount
  with coupons was sacrificed.</p>
</div>
<div class="paragraph">
<p>Surpringly, the quality of the print was much worse that the first print.
There is a lot more warping, and the surface quality is poorer in general.
It seems the engineers placed this model at ~45 deg angle,
  as is visible from the layer lines.
The first order was printed flat, and came out much better.
So, for posterity, during the review process, try to ask to put the model flat.</p>
</div>
<figure class="flexfig">
  <a href="ph-order2-1.webp">
  <img src="ph-order2-1.webp" ></a>
  <a href="ph-order2-2.webp">
  <img src="ph-order2-2.webp"></a>
  <a href="ph-order2-3.webp">
  <img src="ph-order2-3.webp"></a>
  <figcaption></figcaption>
</figure>
<div class="paragraph">
<p>The screw holes are good this time,
  but out of 2 thin slots (which I made larger),
  one was again filled with metal.
I was able to open it with a small slot screwdriver and a hammer.</p>
</div>
</div>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="3d-printing" /><category term="mechanics" /><category term="1/87 scale" /><category term="jlcpcb" /><summary type="html"><![CDATA[JLCPCB&#8217;s 3D printing services offer metal 3D printing, which I wanted to try for some time. Since I got a coupon for it, I finally made an order. The model I wanted to print is a frame for a 1/87 scale truck. The model would benefit from extra weight and of course, compared to resin, metal frame is much more durable.]]></summary></entry><entry><title type="html">A memo about LCSC orders with coupons</title><link href="https://positron96.gitlab.io/2026/02/05/lcsc.html" rel="alternate" type="text/html" title="A memo about LCSC orders with coupons" /><published>2026-02-05T00:00:00+00:00</published><updated>2026-03-29T12:21:43+00:00</updated><id>https://positron96.gitlab.io/2026/02/05/lcsc</id><content type="html" xml:base="https://positron96.gitlab.io/2026/02/05/lcsc.html"><![CDATA[<div class="paragraph">
<p>A short note to myself about discount coupons on LCSC.
Contrary to other JLC sites, on LCSC coupon amount must be lower than the cost of the shopping cart.
On other sites, e.g. JLCPCB, you can apply a higher cost coupon to your order,
  unused coupon amount will be lost.
LCSC factors in coupons on the fly, even before checking out,
  so after your cart gets more expensive then the coupon you have
  (only components are considered, not shipping),
  the price is reduced immediatey by the coupon amount.
The coupon for components (e.g. th one you can get on Oshwlab) cannot be used to reduce shipping cost.
There doesn&#8217;t seem to be a way to choose the coupon if you have more than one applicable.</p>
</div>
<div class="paragraph">
<p>At the time of the order there were some public coupons on shipping ($5 for order of $30, $8 for order of $50, etc).
They stack with components coupons, and applying coupons to reduce cart cost does not remove the shipping discount.</p>
</div>
<figure class="flexfig">
  <a href="scr-lcsc.webp">
  <img src="scr-lcsc.webp" ></a>
  <figcaption>Here I used $40 coupon from oshwlab, exchanged from points, and $5 shipping coupon that the system was giving to everyone at the time</figcaption>
</figure>]]></content><author><name>Paul Melnikov</name></author><category term="electronics" /><category term="lcsc" /><summary type="html"><![CDATA[A short note to myself about discount coupons on LCSC. Contrary to other JLC sites, on LCSC coupon amount must be lower than the cost of the shopping cart. On other sites, e.g. JLCPCB, you can apply a higher cost coupon to your order, unused coupon amount will be lost. LCSC factors in coupons on the fly, even before checking out, so after your cart gets more expensive then the coupon you have (only components are considered, not shipping), the price is reduced immediatey by the coupon amount. The coupon for components (e.g. th one you can get on Oshwlab) cannot be used to reduce shipping cost. There doesn&#8217;t seem to be a way to choose the coupon if you have more than one applicable.]]></summary></entry><entry><title type="html">A Newlib upgrade mystrery story</title><link href="https://positron96.gitlab.io/2026/02/04/newlib-mystery.html" rel="alternate" type="text/html" title="A Newlib upgrade mystrery story" /><published>2026-02-04T00:00:00+00:00</published><updated>2026-02-04T16:11:52+00:00</updated><id>https://positron96.gitlab.io/2026/02/04/newlib-mystery</id><content type="html" xml:base="https://positron96.gitlab.io/2026/02/04/newlib-mystery.html"><![CDATA[<div class="sect1">
<h2 id="introduction">Introduction</h2>
<div class="sectionbody">
<div class="paragraph">
<p>I was working on a DCC decoder project that I recently started.</p>
</div>
<div class="paragraph">
<p>Firstly, I found out a great <a href="https://github.com/ZIMO-Elektronik/DCC">library for DCC devices</a>.
It&#8217;s from ZIMO, actively maintained, so it&#8217;s possible that&#8217;s it&#8217;s what actually powers their products.
It provides both command station building blocks and decoder building blocks.
I quite like that it uses modern C++ and is hardware-agnostic,
 so users can feed it DCC data the way they like it.
What I didn&#8217;t like is that it uses <em>too modern C++</em>, i.e. C++23 features as well as concepts, spans, z-suffixes etc.
I ended up cleaning up the necessary parts to be mostly C++11 and ETL-compatible,
  but also looked at upgrading GCC to higher versions to use some of those fancy features myself.</p>
</div>
<div class="paragraph">
<p>Secondly, the devboard I happen to use for a prototype has a PY32F003x6 with 4Kb of RAM,
  and the percentage used is printed after each compilation.
To my surprise, upgrading from GCC 9.2.1 GCC to 12.3.1 caused an increase of RAM usage
  from about less than a third to almost half!
In absolute terms it&#8217;s going from 1200 to 1900B, but with this small total amount, every big jump is noticable!
It&#8217;s not helping that some RAM must be free for stack and heap, so it definitely cannot go to 100%.</p>
</div>
<div class="paragraph">
<p>GCC 9.3.1:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>RAM:   [===       ]  29.2% (used 1196 bytes from 4096 bytes)
Flash: [==        ]  20.0% (used 6540 bytes from 32768 bytes)</code></pre>
</div>
</div>
<div class="paragraph">
<p>GCC 12.3.1:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>RAM:   [=====     ]  46.3% (used 1896 bytes from 4096 bytes)
Flash: [==        ]  20.7% (used 6792 bytes from 32768 bytes)</code></pre>
</div>
</div>
<div class="paragraph">
<p>In addition, compiling with newer compiler caused output of strange warnings from linker:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code>C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/../../../../arm-none-eabi/bin/ld.exe: C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libc_nano.a(libc_a-closer.o): in function `_close_r':
closer.c:(.text._close_r+0xc): warning: _close is not implemented and will always fail
C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/../../../../arm-none-eabi/bin/ld.exe: C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libc_nano.a(libc_a-lseekr.o): in function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): warning: _lseek is not implemented and will always fail
C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/../../../../arm-none-eabi/bin/ld.exe: C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libc_nano.a(libc_a-readr.o): in function `_read_r':
readr.c:(.text._read_r+0x10): warning: _read is not implemented and will always fail
C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/../../../../arm-none-eabi/bin/ld.exe: C:/Users/user/.platformio/packages/toolchain-gccarmnoneeabi/bin/../lib/gcc/arm-none-eabi/14.2.1/thumb/v6-m/nofp\libc_nano.a(libc_a-writer.o): in function `_write_r':
writer.c:(.text._write_r+0x10): warning: _write is not implemented and will always fail</code></pre>
</div>
</div>
<div class="paragraph">
<p>So, this post is about me investigating the source of this regressions.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="ram-usage">RAM usage</h2>
<div class="sectionbody">
<div class="paragraph">
<p>I generated linker map files for both compilations with <code>-Wl,-Map,output.map,--cref</code> and inspected them in <a href="https://www.sikorskiy.net/info/prj/amap/">AMap</a> viewer.
Immediately it was visible that there are extra 312b used by <code>__sf</code> symbol, coming from <code>_findfp.o</code>.
This was enough information to google,
  and I found out that some users have already noticed this problem:</p>
</div>
<div class="paragraph">
<p>on stackoverflow: <a href="https://stackoverflow.com/questions/78635407/gnu-tools-for-stm32-change-after-version-9-including-non-required-module-and-con" class="bare">https://stackoverflow.com/questions/78635407/gnu-tools-for-stm32-change-after-version-9-including-non-required-module-and-con</a></p>
</div>
<div class="paragraph">
<p>on newlib mailing list: <a href="https://inbox.sourceware.org/newlib/cee20c8a-7881-7cec-07da-ca5b41719b00@embedded-brains.de/t/#u" class="bare">https://inbox.sourceware.org/newlib/cee20c8a-7881-7cec-07da-ca5b41719b00@embedded-brains.de/t/#u</a></p>
</div>
<div class="paragraph">
<p>Mailing list says it was a regression from "splitting up the struct _reent into individual thread-local storage objects" between versions 4.2.0 and 4.3.0.
The discussion is from 2023 and as nothing was done since,
  I assume that unfortunately it is not considered a problem by devs.</p>
</div>
<div class="paragraph">
<p>Studying the code reveals that <code>__sf</code> is an array of 3 FILE objects,
  which predictably are stdin, stdout and stderr handlers.
Size of a file struct is around 100B.</p>
</div>
<div class="paragraph">
<p>Before version 4.3.0 <code>__sf</code> contained much smaller <code>__sFILE_fake</code> file objects,
 which were removed around <a href="https://github.com/cygwin/cygwin/commit/b0cb9f85ca3626e0e68fd451c3090d253ceb4300">June 2022</a>.</p>
</div>
<div class="sect2">
<h3 id="finding-affected-toolchain-versions">Finding affected toolchain versions</h3>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p><strong>Sources</strong></p>
</div>
<div class="paragraph">
<p>Newlib repo is hosted at <a href="https://www.sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git" class="bare">https://www.sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git</a>,
  but it&#8217;s also a repository of Cygwin,
  who host their repo (the same one) at <a href="https://cygwin.com/cgit/newlib-cygwin/" class="bare">https://cygwin.com/cgit/newlib-cygwin/</a>
  and maintain an official GitHub mirror here: <a href="https://github.com/cygwin/cygwin" class="bare">https://github.com/cygwin/cygwin</a>.</p>
</div>
<div class="paragraph">
<p>In a typical ARM project setup, newlib is bundled with ARM gcc compiler.
<a href="https://registry.platformio.org/tools/platformio/toolchain-gccarmnoneeabi/versions">PlatformIO registry</a> is populated by (some) versions from
<a href="https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases">xPack GNU Arm Embedded GCC</a> Project,
  those are populated from
<a href="https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads">ARM GNU Toolchain releases</a>.
The version of newlib in ARM distribution is specified in <code>arm-none-eabi/include/_newlib_version.h</code>.
However, what is written there is the latest release before the source was compiled, as ARM team simply grabs latest commit at the moment of release.
This introduces a problem with one of the releases below.</p>
</div>
<div class="paragraph">
<p>Each release on arm website offers a manifest file which says where the files were taken from,
  this allows to find a specific commit in newlib repo that was used to build the library.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Here are some GCC versions from ARM GCC downloads page and from platformio registry.</p>
</div>
<div class="ulist">
<ul>
<li>
<p>GCC 10.3.1 ships with newlib 4.1.0&#8201;&#8212;&#8201;ok</p>
</li>
<li>
<p>GCC 11.2 has newlib 4.1.0&#8201;&#8212;&#8201;ok.</p>
</li>
<li>
<p>GCC 11.3.rel1 has newlib 4.2.0&#8201;&#8212;&#8201;ok. (<code>_newlib_version.h</code> is broken in this release, so it must be found through commits)</p>
</li>
<li>
<p>GCC 12.2.rel1 - this one is a bit problematic. The version clearly says "4.2.0".
However, the source <a href="https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/12.2.rel1/srcrel/arm-gnu-toolchain-src-snapshot-12.2.rel1-manifest.txt">was taken</a> from commit <a href="https://github.com/cygwin/cygwin/commit/faac79783c27c030ab17a6f298f8aa89c51a03c5">faac797</a>, which is almost a year after version <a href="https://github.com/cygwin/cygwin/tree/newlib-snapshot-20211231">4.2.0</a> was released, and roughly a month before <a href="https://github.com/cygwin/cygwin/tree/newlib-4.3.0">4.3.0</a>.
It already includes __sf symbol in the build&#8201;&#8212;&#8201;<strong>not ok</strong>!</p>
</li>
<li>
<p>GCC 12.3.1 has newlib 4.3.0&#8201;&#8212;&#8201;<strong>not ok</strong>!</p>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="why-is-the-symbol-there-in-the-first-place">Why is the symbol there in the first place?</h3>
<div class="paragraph">
<p>It&#8217;s pulled by using <code>vsnprintf</code> function that I use to print to UART.
Removing calls to <code>vsnprintf</code> removes the symbol too.</p>
</div>
<div class="paragraph">
<p><a href="https://github.com/cygwin/cygwin/blob/main/newlib/libc/stdio/vsniprintf.c">vsniprintf</a>
  is a thin wrapper over _vsniprintf_r function.
_r here means "reentrant", and as a first argument it takes a global <code>_REENT</code> struct.</p>
</div>
<div class="paragraph">
<p>The structure is essentially an array of all global objects,
  including errno and pointers to stdin/out/err file descriptors
  (the <code>__sf</code> entries we are concerned with!).
The struct is also ~80 bytes large.</p>
</div>
<div class="paragraph">
<p>This function creates a fake file descriptor (but fully-sized) and calls _svfprintf_r
  that in turn does the actual formatting.
These functions make frequent use of <code>errno</code> element of <code>_REENT</code>
  and maybe other file-related elements of it.</p>
</div>
<div class="paragraph">
<p>Seemingly <code>vsnprint</code> is the only place where <code>_REENT</code> is used in my program,
  so removing the call allows it,
  along with referenced <code>__sf</code>, to be garbage-collected by linker.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="linker-warnings">Linker warnings</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Other reports and discussions about the problem:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="https://stackoverflow.com/questions/73742774/gcc-arm-none-eabi-11-3-is-not-implemented-and-will-always-fail" class="bare">https://stackoverflow.com/questions/73742774/gcc-arm-none-eabi-11-3-is-not-implemented-and-will-always-fail</a></p>
</li>
<li>
<p><a href="https://community.st.com/t5/stm32cubeide-mcus/build-error/td-p/587816" class="bare">https://community.st.com/t5/stm32cubeide-mcus/build-error/td-p/587816</a></p>
</li>
<li>
<p><a href="https://community.st.com/t5/stm32cubeide-mcus/linker-warnings-on-every-new-project/td-p/791910" class="bare">https://community.st.com/t5/stm32cubeide-mcus/linker-warnings-on-every-new-project/td-p/791910</a></p>
</li>
<li>
<p><a href="https://community.silabs.com/s/question/0D5Vm0000047to9KAA/linker-errors-on-update-to-gnu-arm-v1221?language=en_US" class="bare">https://community.silabs.com/s/question/0D5Vm0000047to9KAA/linker-errors-on-update-to-gnu-arm-v1221?language=en_US</a></p>
</li>
<li>
<p><a href="https://community.arm.com/support-forums/f/compilers-and-libraries-forum/53519/arm-gcc-11-3-rel1-newlib-nano-linker-warning-_read-is-not-implemented-and-will-always-fail" class="bare">https://community.arm.com/support-forums/f/compilers-and-libraries-forum/53519/arm-gcc-11-3-rel1-newlib-nano-linker-warning-_read-is-not-implemented-and-will-always-fail</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It was also mentioned in the newlib mailing list, with no resolution:
<a href="https://inbox.sourceware.org/newlib/CAAHv3KF9Gt0sFtm7Qsx4XfO0iaGHP2n9Z2qS8LdL2ytJcqR%3Deg%40mail.gmail.com" class="bare">https://inbox.sourceware.org/newlib/CAAHv3KF9Gt0sFtm7Qsx4XfO0iaGHP2n9Z2qS8LdL2ytJcqR%3Deg%40mail.gmail.com</a></p>
</div>
<div class="paragraph">
<p>While I found no reliable and non-hacky solution,
  in the links above it is stated that the problem appeared in v11.3 of Arm GNU Toolchain.
Indeed, after looking myself at the files, I found that starting with v11.3, file libnosys.a contains sections ".gnu.warning" (e.g. ".gnu.warning._write"), which cause the linker to produce the warnings
(this feature of LD linker is described in <a href="https://sourceware.org/binutils/docs/ld/Special-Sections.html">its documentation</a>).
In 11.2 these sections are  not present.</p>
</div>
<div class="paragraph">
<p>In newlib codebase, these warnings have been there for at least 27 years,
  so something in the process of building the library changed between 11.2 and 11.3.
The warnings are still there in Arm GNU Toolchain v12 and v14.</p>
</div>
<div class="paragraph">
<p>The warnings are from linker, not from compiler, so they cannot be supressed with <code>-W</code> flags.</p>
</div>
<div class="paragraph">
<p>At the time of writing, my <a href="https://community.arm.com/support-forums/f/compilers-and-libraries-forum/57593/request-remove-gnu-warning-sections-from-newlib-introduced-in-arm-gnu-toolchain-11-3">request for clarifications</a> on ARM&#8217;s forum is not answered.</p>
</div>
<div class="paragraph">
<p>It seems that one workaround is to go ST&#8217;s way and supply stubs for these functions manually.
However it somewhat defeats the purpose of using nosys in the first place
  (whose goal is to provide these stubs).</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="outcome">Outcome</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Latest version in PlatformIO registry that is unaffected by both problems is 10 (10.3.1).
It has moderate support for C++20 features, e.g. concepts, but almost no support for C++23.</p>
</div>
<div class="paragraph">
<p>For those who are not tied to platformio, GCC 12.2r1 should also work and not have these problems.</p>
</div>
<div class="paragraph">
<p>Also, since I use ETL extensively, a recently added etl::format is of interest as a potential replacement of sprintf.</p>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<i class="fa icon-caution" title="Caution"></i>
</td>
<td class="content">
It turns out, GCC 10 does not play well with debugging with blackmagic-debug.
Its GDB complains about register mismatching packet.
Older and later GCC versions, e.g. 14, do not show this problem.
Which means I&#8217;m somewhat back to square one with selection of GCC version.
I am now considering to use latest GCC,
  not use newlib printf functions family and use a 3rd party implementation,
  in particular <a href="https://github.com/charlesnicholson/nanoprintf?tab=readme-ov-file">nanoprintf</a>.
It seems to be feature-rich enough while still being small enough.
It&#8217;s also actively maintained.
However, the problem with linker warning would still be there.
</td>
</tr>
</table>
</div>
</div>
</div>]]></content><author><name>Paul Melnikov</name></author><category term="programming" /><category term="gcc" /><category term="embedded" /><summary type="html"><![CDATA[Investigating some regressions when upgrading arm-gcc toolchain]]></summary></entry></feed>