<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.2.2">Jekyll</generator><link href="https://gabortoth.hu/feed.xml" rel="self" type="application/atom+xml" /><link href="https://gabortoth.hu/" rel="alternate" type="text/html" /><updated>2025-11-07T10:29:19+01:00</updated><id>https://gabortoth.hu/feed.xml</id><title type="html">personal stuff, etc.</title><subtitle>Gabor Toth&apos;s personal blog. Read only. Random frequency. To improve your experience, our website DOES NOT use cookies.</subtitle><entry><title type="html">Quick-win túraútvonal app</title><link href="https://gabortoth.hu/tech/2025/11/02/ultimate-kir%C3%A1ndul%C3%B3s-app.html" rel="alternate" type="text/html" title="Quick-win túraútvonal app" /><published>2025-11-02T08:35:02+01:00</published><updated>2025-11-02T08:35:02+01:00</updated><id>https://gabortoth.hu/tech/2025/11/02/ultimate-kir%C3%A1ndul%C3%B3s-app</id><content type="html" xml:base="https://gabortoth.hu/tech/2025/11/02/ultimate-kir%C3%A1ndul%C3%B3s-app.html"><![CDATA[<p>Valószínűleg a hardcore túrázók sokkal kifinomultabb eszközökkel dolgoznak - viszont, mivel óráim mentek rá ezeknek a dolgoknak a researchelésére, szeretnék egy egyszerű dolgot mutatni a hozzám hasonló koca-túrázóknak.</p>

<p>Először is, túrához ajánlom a Természetjáró appot. Minden egyéb kiegészítéstől függetlenül jól mutatja a legkisebb ösvényeket is, tehát ha nagyjából tudjuk, hogy merre megyünk, pl egy leírás alapján, akkor ez kiegészítésnek tökéletes. Meg tudjuk nézni, merre visz az ösvény, amin vagyunk. Sajnos szín jelölés nincs rajta, vagy legalábbis nem találtam meg.</p>

<p>Viszont, be lehet tölteni .gpx fájlokat. Ezek egyszerű, útvonalat leíró fájlok, amik például a <a href="https://kirandulastippek.hu/">kirandulastippek.hu</a> oldalról is letölthetők. Nagy meglepetésemre ezek nem tölthetők be a Google Maps-be vagy az Apple Maps-be sem, viszont Természetjáró appba igen.</p>

<p>Ezt teljes körűen le lehet játszani mobilon, akár a helyszínen is, persze a legprofibb előre felkészülni.</p>

<p>A Természetjáró app-ban a tervezés alatt van egy “GPX-nyomvonal feltöltése” lehetőség:</p>

<p><img src="/images/IMG_5168.PNG" alt="Természetjáró - tervezés" /></p>

<p>Itt kiválaszthatjuk az előzőleg, tetszőleges forrásból (pl kirandulastippek.hu) letöltött .gpx fájlokat:</p>

<p><img src="/images/IMG_5169.PNG" alt="Természetjáró - tervezés" /></p>

<p>Az útvonal szépen megjelenik, és követhetjük valós időben, hogy hol tartunk:</p>

<p><img src="/images/IMG_5170.PNG" alt="Természetjáró - tervezés" /></p>]]></content><author><name></name></author><category term="tech" /><category term="kirándulás," /><category term="túra," /><category term="útvonal" /><summary type="html"><![CDATA[Valószínűleg a hardcore túrázók sokkal kifinomultabb eszközökkel dolgoznak - viszont, mivel óráim mentek rá ezeknek a dolgoknak a researchelésére, szeretnék egy egyszerű dolgot mutatni a hozzám hasonló koca-túrázóknak. Először is, túrához ajánlom a Természetjáró appot. Minden egyéb kiegészítéstől függetlenül jól mutatja a legkisebb ösvényeket is, tehát ha nagyjából tudjuk, hogy merre megyünk, pl egy leírás alapján, akkor ez kiegészítésnek tökéletes. Meg tudjuk nézni, merre visz az ösvény, amin vagyunk. Sajnos szín jelölés nincs rajta, vagy legalábbis nem találtam meg. Viszont, be lehet tölteni .gpx fájlokat. Ezek egyszerű, útvonalat leíró fájlok, amik például a kirandulastippek.hu oldalról is letölthetők. Nagy meglepetésemre ezek nem tölthetők be a Google Maps-be vagy az Apple Maps-be sem, viszont Természetjáró appba igen. Ezt teljes körűen le lehet játszani mobilon, akár a helyszínen is, persze a legprofibb előre felkészülni. A Természetjáró app-ban a tervezés alatt van egy “GPX-nyomvonal feltöltése” lehetőség: Itt kiválaszthatjuk az előzőleg, tetszőleges forrásból (pl kirandulastippek.hu) letöltött .gpx fájlokat: Az útvonal szépen megjelenik, és követhetjük valós időben, hogy hol tartunk:]]></summary></entry><entry><title type="html">Fix heading numbering in Microsoft Word</title><link href="https://gabortoth.hu/tech/2025/07/05/fix-heading-numbering-in-microsoft-word.html" rel="alternate" type="text/html" title="Fix heading numbering in Microsoft Word" /><published>2025-07-05T13:23:12+02:00</published><updated>2025-07-05T13:23:12+02:00</updated><id>https://gabortoth.hu/tech/2025/07/05/fix-heading-numbering-in-microsoft-word</id><content type="html" xml:base="https://gabortoth.hu/tech/2025/07/05/fix-heading-numbering-in-microsoft-word.html"><![CDATA[<p>Unfortunately, the numbering of my Word headings often goes wrong. It unexpectedly restarts from the beginning (1, 1.1, 1.1.1), and choosing to continue numbering from the quick menu doesn’t help. This usually occurs when several parties with different Word versions modify the same file and forward it to each other. This is, of course, not good practice, but it’s unavoidable at times.</p>

<p>The last time we worked with a client on a document, the same mistake happened again. In this situation, that mistake would have been unacceptable.  I decided to solve this problem once and for all.</p>

<p>As an aside, many years ago, I migrated a document to LaTeX in a similar situation. That didn’t end well because, although the client was happy with the result, he wanted to make regular changes that he couldn’t do himself.</p>

<p>So now I decided to solve this problem once and for all, within Word. I wrote the code using AI, but as it performed surprisingly poorly (perhaps Visual Basic is under-represented on the net compared to more popular programming languages?), I had to go step by step, and gradually incorporated the solution to a problem into the solution.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Sub ListHeadingParagraphsToNewDoc_Final()
    Dim newDoc As Document
    Dim originalDoc As Document
    
    Dim para As Paragraph
    Dim out As String
    Dim msg As String
    
    Set originalDoc = ActiveDocument
    Set newDoc = Documents.Add

    originalDoc.Activate
    For Each para In ActiveDocument.Paragraphs
        If para.Style Like "Heading*" Or para.Style Like "*msor*" Then
            msg = ""
            With para.Range.ListFormat
                If .ListType &lt;&gt; wdListNoNumbering Then
                    levelIndex = .ListLevelNumber
                    msg = msg &amp; "Levelindex: " &amp; levelIndex &amp; vbCrLf
                    msg = msg &amp; "Visible numbering (ListString): " &amp; .ListString &amp; vbCrLf
        
                    If Not .listTemplate Is Nothing Then
                        Set listTemplate = .listTemplate
                        If levelIndex &gt;= 1 And levelIndex &lt;= listTemplate.ListLevels.Count Then
                            Set listLevel = listTemplate.ListLevels(levelIndex)
                            msg = msg &amp; "NumberFormat: " &amp; listLevel.NumberFormat &amp; vbCrLf
                            msg = msg &amp; "StartAt: " &amp; listLevel.StartAt &amp; vbCrLf
                            msg = msg &amp; "LinkedStyle: " &amp; listLevel.LinkedStyle &amp; vbCrLf
                            msg = msg &amp; "NumberStyle: " &amp; listLevel.NumberStyle &amp; vbCrLf
                            msg = msg &amp; "NumberPosition: " &amp; listLevel.NumberPosition &amp; vbCrLf
                            msg = msg &amp; "TextPosition: " &amp; listLevel.TextPosition &amp; vbCrLf
                            listLevel.LinkedStyle = para.Style
                        Else
                            msg = msg &amp; "[ListLevel not accessible]" &amp; vbCrLf
                        End If
                    Else
                        msg = msg &amp; "[There is no ListTemplate]" &amp; vbCrLf
                    End If
                Else
                    msg = msg &amp; "[There is no numbering]" &amp; vbCrLf
                End If
            End With
            
            out = "Style: " &amp; para.Style &amp; vbCrLf &amp; _
                    msg &amp; _
                   "Text: " &amp; Replace(para.Range.Text, vbCr, "") &amp; vbCrLf
            Debug.Print out
            newDoc.Content.InsertAfter out &amp; vbCrLf
            
        End If
    Next para

    newDoc.Activate"

    'MsgBox "Ready!", vbInformation
End Sub
</code></pre></div></div>

<p>The root of the problem is that the heading style loses the “linkedStyle” property somehow, so the numbering is not applied consistently. I’m not sure why this is happening. The user interface seems to apply the styles and headings correctly. It may be caused by editing the file with a mix of English and Hungarian Word, or perhaps the versions are different.</p>

<p>The solution lies in the line “listLevel.LinkedStyle = para.Style,” where we fix the missing style link. The macro logs to a separate document for debugging purposes.</p>]]></content><author><name></name></author><category term="tech" /><category term="word," /><category term="heading," /><category term="numbering," /><category term="microsoft" /><summary type="html"><![CDATA[Unfortunately, the numbering of my Word headings often goes wrong. It unexpectedly restarts from the beginning (1, 1.1, 1.1.1), and choosing to continue numbering from the quick menu doesn’t help. This usually occurs when several parties with different Word versions modify the same file and forward it to each other. This is, of course, not good practice, but it’s unavoidable at times. The last time we worked with a client on a document, the same mistake happened again. In this situation, that mistake would have been unacceptable. I decided to solve this problem once and for all. As an aside, many years ago, I migrated a document to LaTeX in a similar situation. That didn’t end well because, although the client was happy with the result, he wanted to make regular changes that he couldn’t do himself. So now I decided to solve this problem once and for all, within Word. I wrote the code using AI, but as it performed surprisingly poorly (perhaps Visual Basic is under-represented on the net compared to more popular programming languages?), I had to go step by step, and gradually incorporated the solution to a problem into the solution. Sub ListHeadingParagraphsToNewDoc_Final() Dim newDoc As Document Dim originalDoc As Document Dim para As Paragraph Dim out As String Dim msg As String Set originalDoc = ActiveDocument Set newDoc = Documents.Add originalDoc.Activate For Each para In ActiveDocument.Paragraphs If para.Style Like "Heading*" Or para.Style Like "*msor*" Then msg = "" With para.Range.ListFormat If .ListType &lt;&gt; wdListNoNumbering Then levelIndex = .ListLevelNumber msg = msg &amp; "Levelindex: " &amp; levelIndex &amp; vbCrLf msg = msg &amp; "Visible numbering (ListString): " &amp; .ListString &amp; vbCrLf If Not .listTemplate Is Nothing Then Set listTemplate = .listTemplate If levelIndex &gt;= 1 And levelIndex &lt;= listTemplate.ListLevels.Count Then Set listLevel = listTemplate.ListLevels(levelIndex) msg = msg &amp; "NumberFormat: " &amp; listLevel.NumberFormat &amp; vbCrLf msg = msg &amp; "StartAt: " &amp; listLevel.StartAt &amp; vbCrLf msg = msg &amp; "LinkedStyle: " &amp; listLevel.LinkedStyle &amp; vbCrLf msg = msg &amp; "NumberStyle: " &amp; listLevel.NumberStyle &amp; vbCrLf msg = msg &amp; "NumberPosition: " &amp; listLevel.NumberPosition &amp; vbCrLf msg = msg &amp; "TextPosition: " &amp; listLevel.TextPosition &amp; vbCrLf listLevel.LinkedStyle = para.Style Else msg = msg &amp; "[ListLevel not accessible]" &amp; vbCrLf End If Else msg = msg &amp; "[There is no ListTemplate]" &amp; vbCrLf End If Else msg = msg &amp; "[There is no numbering]" &amp; vbCrLf End If End With out = "Style: " &amp; para.Style &amp; vbCrLf &amp; _ msg &amp; _ "Text: " &amp; Replace(para.Range.Text, vbCr, "") &amp; vbCrLf Debug.Print out newDoc.Content.InsertAfter out &amp; vbCrLf End If Next para newDoc.Activate" 'MsgBox "Ready!", vbInformation End Sub The root of the problem is that the heading style loses the “linkedStyle” property somehow, so the numbering is not applied consistently. I’m not sure why this is happening. The user interface seems to apply the styles and headings correctly. It may be caused by editing the file with a mix of English and Hungarian Word, or perhaps the versions are different. The solution lies in the line “listLevel.LinkedStyle = para.Style,” where we fix the missing style link. The macro logs to a separate document for debugging purposes.]]></summary></entry><entry><title type="html">Convert EOV coordinates to GPS</title><link href="https://gabortoth.hu/tech/2023/10/10/convert-eov-to-gps.html" rel="alternate" type="text/html" title="Convert EOV coordinates to GPS" /><published>2023-10-10T13:47:32+02:00</published><updated>2023-10-10T13:47:32+02:00</updated><id>https://gabortoth.hu/tech/2023/10/10/convert-eov-to-gps</id><content type="html" xml:base="https://gabortoth.hu/tech/2023/10/10/convert-eov-to-gps.html"><![CDATA[<p>Many systems in Hungary store geographical coordinates in EOV projection. Often, these need to be converted to GPS, which is easier to work with (or… or even more difficult, in some cases I prefer EOV).</p>

<p>More precisely, it is a matter of converting <a href="https://epsg.io/23700">EPSG:23700</a> (EOV) format to <a href="https://epsg.io/4326">WGS 84</a></p>

<p>After some research, I found that the easiest, and most easily scriptable way to do this is using <a href="https://proj.org">PROJ</a></p>

<p>Installation (on Ubuntu, but there are <a href="https://proj.org/en/9.3/install.html">many other options</a>):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install proj-bin
</code></pre></div></div>

<p>Convert EOV to GPS:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ echo 651804.2509374797 237667.6262724590 | cs2cs -f "%.10f" EPSG:23700 EPSG:4326
47.4829506012   19.0713855051 0.0000000000
</code></pre></div></div>]]></content><author><name></name></author><category term="tech" /><category term="eov," /><category term="gps," /><category term="spatial," /><category term="convert," /><category term="wgs" /><category term="84" /><summary type="html"><![CDATA[Many systems in Hungary store geographical coordinates in EOV projection. Often, these need to be converted to GPS, which is easier to work with (or… or even more difficult, in some cases I prefer EOV). More precisely, it is a matter of converting EPSG:23700 (EOV) format to WGS 84 After some research, I found that the easiest, and most easily scriptable way to do this is using PROJ Installation (on Ubuntu, but there are many other options): apt install proj-bin Convert EOV to GPS: $ echo 651804.2509374797 237667.6262724590 | cs2cs -f "%.10f" EPSG:23700 EPSG:4326 47.4829506012 19.0713855051 0.0000000000]]></summary></entry><entry><title type="html">Set MX record for Google Mail on CPanel</title><link href="https://gabortoth.hu/tech/2023/04/22/set-mx-record-for-google-mail-on-cpanel.html" rel="alternate" type="text/html" title="Set MX record for Google Mail on CPanel" /><published>2023-04-22T19:02:32+02:00</published><updated>2023-04-22T19:02:32+02:00</updated><id>https://gabortoth.hu/tech/2023/04/22/set-mx-record-for-google-mail-on-cpanel</id><content type="html" xml:base="https://gabortoth.hu/tech/2023/04/22/set-mx-record-for-google-mail-on-cpanel.html"><![CDATA[<p>That’s too crazy to not to write about:</p>

<p>For activate e-mail service in Google Business Suite, you need to set <code class="language-plaintext highlighter-rouge">@</code> or empty string in “Host record” field of an MX record of your domain. 
However, you cannot set either, you get validation error from CPanel.</p>

<p>Solution: enter domain name and a dot (<code class="language-plaintext highlighter-rouge">.</code>), e.g. <code class="language-plaintext highlighter-rouge">domain.net.</code> into host record field (<a href="https://forums.cpanel.net/threads/problem-setting-up-txt-record-in-dns.656663/post-2713997">see this answer on CPanel forum</a>).</p>]]></content><author><name></name></author><category term="tech" /><category term="gmail," /><category term="cpanel," /><category term="google," /><category term="mail" /><summary type="html"><![CDATA[That’s too crazy to not to write about: For activate e-mail service in Google Business Suite, you need to set @ or empty string in “Host record” field of an MX record of your domain. However, you cannot set either, you get validation error from CPanel. Solution: enter domain name and a dot (.), e.g. domain.net. into host record field (see this answer on CPanel forum).]]></summary></entry><entry><title type="html">Bye-bye Wordpress, welcome Jekyll!</title><link href="https://gabortoth.hu/jekyll/update/2021/12/29/bye-bye-wordpress.html" rel="alternate" type="text/html" title="Bye-bye Wordpress, welcome Jekyll!" /><published>2021-12-29T11:13:32+01:00</published><updated>2021-12-29T11:13:32+01:00</updated><id>https://gabortoth.hu/jekyll/update/2021/12/29/bye-bye-wordpress</id><content type="html" xml:base="https://gabortoth.hu/jekyll/update/2021/12/29/bye-bye-wordpress.html"><![CDATA[<p>I’ve been looking for a static solution instead of Wordpress for a long time, as it’s completely pointless to burn processor cores and nerves with unnecessary and slow functions.</p>

<p><a href="https://jekyllrb.com">Jekyll</a>, here we are.</p>

<p>Jekyll allows information to be stored in a simpler format that is easier to work with.
Markdown is certainly much better for this than Wordpress posts. There are basically two layers to the solution: the document format (markdown) and the blog engine (Jekyll).</p>

<p>Markdown meets the basic requirements for document formatting (headings, paragraphs, numbering, bullets, images, links) and
“there is a way forward” to more sophisticated formats, be it Word, HTML, LaTex, PDF.</p>

<h1 id="migrating-wordpress-posts">Migrating Wordpress posts</h1>

<p>In Wordpress: <code class="language-plaintext highlighter-rouge">Tools &gt; Export &gt; All content &gt; Download Export File</code></p>

<p>From command prompt (don’t need to install anything, except node &gt;=12.14):</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>npx wordpress-export-to-markdown --post-folders=false --prefix-date=true export.xml
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">--post-folders=false --prefix-date=true</code> option puts meta info for Jekyll in markdown files. Yeyy!</p>

<p>Checkout: <a href="https://www.npmjs.com/package/wordpress-export-to-markdown">https://www.npmjs.com/package/wordpress-export-to-markdown</a></p>

<p>Then all we have to do is pick and choose what we want to keep and it can go to Jekyll.</p>

<p>See the <a href="https://jekyllrb.com/docs/home">Jekyll docs</a> for more information on how to get the most out of Jekyll. Submut any bugs/feature requests to <a href="https://github.com/jekyll/jekyll">Jekyll’s GitHub repo</a>. If you have questions, you can ask them on <a href="https://talk.jekyllrb.com/">Jekyll Talk</a>.</p>]]></content><author><name></name></author><category term="jekyll" /><category term="update" /><category term="wordpress," /><category term="jekyll," /><category term="blog" /><summary type="html"><![CDATA[I’ve been looking for a static solution instead of Wordpress for a long time, as it’s completely pointless to burn processor cores and nerves with unnecessary and slow functions.]]></summary></entry><entry><title type="html">Raspberry PI Private Server With Manjaro</title><link href="https://gabortoth.hu/projects/2021/11/12/raspberry-pi-private-server-with-manjaro.html" rel="alternate" type="text/html" title="Raspberry PI Private Server With Manjaro" /><published>2021-11-12T11:13:32+01:00</published><updated>2021-11-12T11:13:32+01:00</updated><id>https://gabortoth.hu/projects/2021/11/12/raspberry-pi-private-server-with-manjaro</id><content type="html" xml:base="https://gabortoth.hu/projects/2021/11/12/raspberry-pi-private-server-with-manjaro.html"><![CDATA[<h1 id="motivation">Motivation</h1>
<p>Instead of using a VPS or other 3rd party service build a private, low cost, silent home server.</p>

<h1 id="useful-stuff">Useful stuff:</h1>

<p>Check <a href="pacman docs">https://linuxhint.com/manjaro-package-manager-pacman/</a>.</p>

<p>Temperature:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/opt/vc/bin/vcgencmd measure_temp
</code></pre></div></div>

<p>Update packages:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -Syu
</code></pre></div></div>

<p>Install some tools:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo pacman -S networkmanager vim mc htop wget
</code></pre></div></div>

<p>Start networkmanager:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start NetworkManager
</code></pre></div></div>

<p>Auto start on boot:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl enable NetworkManager
</code></pre></div></div>

<p>Config network:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo nmtui
</code></pre></div></div>

<p>Here you will add your wifi device and configure it. Yo can enable the Security and enter your password if so inclined. The important things to not forget to do is enable these 2 lines before you save and exit:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[X] Automatically connect
[X] Available to all users
</code></pre></div></div>

<p>Stop MAC spoofing - for some reasons I needed to stop it:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo vim /etc/NetworkManager/conf.d/100-disable-wifi-mac-randomization.conf
</code></pre></div></div>
<p>with content:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[device]
wifi.scan-rand-mac-address=no
</code></pre></div></div>

<p>reboot…</p>

<h1 id="install-gitea">Install Gitea</h1>

<p>Find an arm-linux version in https://dl.gitea.io/gitea/1.15.6/.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wget -O gitea https://dl.gitea.io/gitea/1.15.6/gitea-1.15.6-linux-arm64
</code></pre></div></div>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo useradd \
   --system \
   --shell /bin/bash \
   --user-group \
   --disabled-password \
   --home-dir /home/git \
   git
</code></pre></div></div>

<p><em>(to be continued - hopefully…)</em></p>]]></content><author><name></name></author><category term="projects" /><category term="raspberry," /><category term="manjaro," /><category term="pi" /><summary type="html"><![CDATA[Motivation Instead of using a VPS or other 3rd party service build a private, low cost, silent home server.]]></summary></entry><entry><title type="html">The Ultimate MP3 Player</title><link href="https://gabortoth.hu/projects/2021/10/09/the-ultimate-mp3-player.html" rel="alternate" type="text/html" title="The Ultimate MP3 Player" /><published>2021-10-09T12:13:32+02:00</published><updated>2021-10-09T12:13:32+02:00</updated><id>https://gabortoth.hu/projects/2021/10/09/the-ultimate-mp3-player</id><content type="html" xml:base="https://gabortoth.hu/projects/2021/10/09/the-ultimate-mp3-player.html"><![CDATA[<p><em>This is a work-in-progress project.</em></p>

<h1 id="introduction">Introduction</h1>
<p>Build the ultimate MP3 player - ultimate, becuase you might not want to buy
any other mp3 player anymore!</p>

<p>Let’s see the components needed:</p>

<ul>
  <li>Attiny85</li>
  <li>Dfplayer</li>
</ul>

<p>Ok, I am a cheater with this Dfplayer-thing, but don’t worry, it won’t be so easy. We will do it step by step.</p>

<ol>
  <li>Learn programming Attiny85 (<a href="/elektro/2021/03/02/progrmming-attiny85-with-arduino.html">see this earlier post</a>)</li>
  <li>Control Dfplayer with Attiny85</li>
  <li>Make it portable: use joule thief</li>
</ol>

<p>Ok, so let’s do the thing.</p>

<h1 id="playing-with-dfplayer">Playing with DFplayer</h1>

<p>Dfplayer uses an SD card to store music. It <a href="https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299">supports FAT16 , FAT32 file system, maximum
 support 32G of the TF card, support 32G of U disk, 64M bytes NORFLASH</a>.</p>

<p>https://wiki.dfrobot.com/DFPlayer_Mini_SKU_DFR0299</p>

<p>DFPlayer can work in 3 modes:</p>
<ol>
  <li>serial</li>
  <li>AD KEY</li>
  <li>IO mode</li>
</ol>

<p>Now, for our purposes use serial mode. In serial mode we can control DFPlayer with some sort of byte commands. It leads us 
quite quick to create a lib for it, but fortunately we can find many. Let’s see some! (In Arduino IDE: Tools -&gt; Manage Libraries -&gt; Search for DFPlayer) You should
choose <code class="language-plaintext highlighter-rouge">DFRobotDFPlayerMini</code>.</p>

<h2 id="pinout">Pinout</h2>

<p><img src="/images/DFPlayer_Mini.png" alt="DFPlayer pinout" /></p>

<p>Lets set up the following pinout:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>(Nano) D11 - 1K Ohm resistor - RX
(Nano) D10 - TX
(Nano) GND - GND
(Nano) 5V - VCC
(Stereo Jack) R - SPK_1
(Stereo Jack) L - SPK_2
(Stereo Jack) GND - GND
</code></pre></div></div>

<p>Find code here: <a href="/upload/dfplayer_test.ino">dfplayer_test.ino</a></p>

<p><code class="language-plaintext highlighter-rouge">Sketch uses 5356 bytes </code> - not bad, we will have 8k in case of Attiny85.</p>

<p><em>(to be continued…)</em></p>]]></content><author><name></name></author><category term="projects" /><category term="mp3," /><category term="dfplayer," /><category term="attiny," /><category term="attiny85" /><summary type="html"><![CDATA[This is a work-in-progress project.]]></summary></entry><entry><title type="html">Is immutability enough?</title><link href="https://gabortoth.hu/programming/2021/10/04/is-immutability-enough.html" rel="alternate" type="text/html" title="Is immutability enough?" /><published>2021-10-04T12:13:32+02:00</published><updated>2021-10-04T12:13:32+02:00</updated><id>https://gabortoth.hu/programming/2021/10/04/is-immutability-enough</id><content type="html" xml:base="https://gabortoth.hu/programming/2021/10/04/is-immutability-enough.html"><![CDATA[<p>There is <a href="https://news.ycombinator.com/item?id=27642263">this thread</a> and
 <a href="https://codewords.recurse.com/issues/six/immutability-is-not-enough">this article</a>.</p>

<p>It’s a bit old, but it is being posted and retweeted regurarly.
You read it, and… you know, you see the point, but <em>something</em> is not right with it.</p>

<blockquote>
  <p>It turns out that our purely functional rendering code is sensitive to ordering in
 non-obvious ways. The first time I encountered this kind of bug, it felt strangely
 familiar – it’s something that often occurs in imperative programs. This is exactly
 the kind of problem that functional programming was supposed to help us avoid!</p>
</blockquote>

<p>There is a quite good <a href="https://news.ycombinator.com/item?id=27643731">reaction on Reddit</a>. I couldn’t react more accurate:</p>

<blockquote>
  <p>Moving the character and collision detection should not be two separate function that
 affect the state but that can be called separately (or in the wrong order) and keep the
 system in an incorrect state. Only the code responsible for modifying the state should do
 so, and it should guarantee to leave it in a correct state on returning. Moving without
 collision detection can leave the system in an incorrect state and thus should not even
 be a function that exists.</p>
</blockquote>

<p>However, the moral of the story is right:</p>

<blockquote>
  <p>After experiencing the kinds of bugs I described above, it became clear to me that
 – despite their merits – immutable data structures are not a silver bullet.</p>
</blockquote>

<p>Of course. Software systems can be too complex to solve most of complexity related problems
with one simple concept like immutability.</p>]]></content><author><name></name></author><category term="programming" /><category term="immutability" /><summary type="html"><![CDATA[There is this thread and this article.]]></summary></entry><entry><title type="html">Programming Attiny85 with Arduino Nano</title><link href="https://gabortoth.hu/elektro/2021/03/02/progrmming-attiny85-with-arduino.html" rel="alternate" type="text/html" title="Programming Attiny85 with Arduino Nano" /><published>2021-03-02T00:00:00+01:00</published><updated>2021-03-02T00:00:00+01:00</updated><id>https://gabortoth.hu/elektro/2021/03/02/progrmming-attiny85-with-arduino</id><content type="html" xml:base="https://gabortoth.hu/elektro/2021/03/02/progrmming-attiny85-with-arduino.html"><![CDATA[<p><a href="https://create.arduino.cc/projecthub/arjun/programming-attiny85-with-arduino-uno-afb829">Based on this quite good description</a> I’ve made a circuit to program Attiny85.
In this way, it is reposted with rather little additional value, but perhaps in a more understandable way.
It will be fun!</p>

<p>Required parts:</p>

<ul>
  <li>Arduino Nano</li>
  <li>Attiny85</li>
  <li>10 uF electrolytic capacitor</li>
  <li>LED</li>
</ul>

<h2 id="isp-in-system-programming-mode">ISP (In-system Programming) mode</h2>

<p>Put the Arduino Nano in ISP mode. Fortunately, you can find an example of this in the Arduino IDE: <code class="language-plaintext highlighter-rouge">File -&gt; Examples -&gt; ArduinoISP</code> - upload without modification.</p>

<h2 id="add-attiny85-support-to-arduino-ide">Add Attiny85 support to Arduino IDE</h2>

<p>Under <code class="language-plaintext highlighter-rouge">File -&gt; Preferences -&gt; Additional Boards Manager URLs</code>, enter the following: <code class="language-plaintext highlighter-rouge">https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json</code>. (<a href="/upload/package_damellis_attiny_index.json">mirror</a>)</p>

<p><em>(If you find the URL unusable in the meantime, check out <a href="https://github.com/damellis/attiny">David A. Mellis’ Github</a>.)</em></p>

<p>Under <code class="language-plaintext highlighter-rouge">Tools -&gt; Board -&gt; Boards manager</code> choose <em>“attiny”</em> (by David A. Mellis) and install it.</p>

<p>If all goes well, you will see “Attiny” under <code class="language-plaintext highlighter-rouge">Tools-&gt;Board</code>.</p>

<h2 id="connecting-attiny85-with-arduino">Connecting Attiny85 with Arduino</h2>

<p>Check Attiny85 pinout:</p>

<p><img src="/images/ATtiny85-Pinout.png" alt="https://components101.com/microcontroller/attiny85-pinout-datasheet" /></p>

<p>(<a href="https://components101.com/microcontroller/attiny85-pinout-datasheet">source</a>)</p>

<p>Arduino Nano - Attiny85 connection:</p>

<ul>
  <li>5V - VCC</li>
  <li>GND - GND</li>
  <li>D13 - PB2</li>
  <li>D12 - PB1</li>
  <li>D11 - PB0</li>
  <li>D10 - PB5 (RESET)</li>
  <li>RST - 10 uF C - GND*</li>
</ul>

<p><em>*The original description incorrectly states that the anode (+) of the electrolytic capacitor should be connected to GND, of course the cathode should be connected to GND.</em></p>

<h2 id="prepare-uploading-attiny85">Prepare uploading Attiny85</h2>

<p>In Arduino IDE select the following options:</p>

<ul>
  <li>Tools -&gt; Board: Attiny25/45/85</li>
  <li>Tools -&gt; Processor: Attiny85</li>
  <li>Tools -&gt; Clock: Internal 8MHz</li>
  <li>Tools -&gt; Programmer: Arduino as ISP*</li>
</ul>

<p><em>*Note that we usually use AVRISP mkii for Arduino…</em></p>

<p>By default Attiny85 runs at 1MHz, so you need to <code class="language-plaintext highlighter-rouge">Tools -&gt; Burn Bootloader</code>.</p>

<h2 id="test-it">Test it!</h2>

<p>If everything went well so far, open the blink example (<code class="language-plaintext highlighter-rouge">File -&gt; Examples -&gt; Basics -&gt; Blink</code>). Change the pin from 13 to 0. (Or from <code class="language-plaintext highlighter-rouge">LED_BUILTIN</code> to 0.) Upload.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED\_BUILTIN as an output.
  pinMode(0, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(0, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);             // wait for a second
  digitalWrite(0, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);             // wait for a second
}
</code></pre></div></div>

<p>Now, this is harder to test than an usual Arduino app, because you need a separate power source to drive the Attiny. In the original descripton, a 3V button cell is used. But you can also draw the required current from the Arduino (disconnect the original wiring, of course):</p>

<ul>
  <li>PB0 - LED - GND</li>
  <li>3.3V - VCC</li>
  <li>GND - GND</li>
</ul>

<p><em>Profit!</em></p>

<h2 id="errors">Errors</h2>

<p>Under Arduino IDE 2.x you may get <em>“A programmer is required to upload”</em> error. Use <code class="language-plaintext highlighter-rouge">Sketch -&gt; Upload Using Programmer</code> when uploading to your ATtiny85. (<a href="https://forum.arduino.cc/t/cant-program-attiny85-with-attinycore-v1-5-2/701346">ref</a>)</p>]]></content><author><name></name></author><category term="elektro" /><category term="arduino" /><summary type="html"><![CDATA[Based on this quite good description I’ve made a circuit to program Attiny85. In this way, it is reposted with rather little additional value, but perhaps in a more understandable way. It will be fun!]]></summary></entry></feed>