{"id":7998,"date":"2024-08-14T12:02:32","date_gmt":"2024-08-14T10:02:32","guid":{"rendered":"https:\/\/willem.aandewiel.nl\/?p=7998"},"modified":"2024-08-25T10:42:58","modified_gmt":"2024-08-25T08:42:58","slug":"conversie-arduino-naar-platformio-project","status":"publish","type":"post","link":"https:\/\/willem.aandewiel.nl\/index.php\/2024\/08\/14\/conversie-arduino-naar-platformio-project\/","title":{"rendered":"Conversie Arduino- naar PlatformIO-project"},"content":{"rendered":"\n<p>[ 2,865 keer bekeken \/ views ] <br><br>Voor een vriend heb ik hardware ontwikkeld om de vloerverwarming van zijn huis effectiever en effici\u00ebnter te regelen. Om deze hardware te kunnen testen schreef ik software met de Arduino IDE. Voor mij de enige manier die ik kende.<\/p>\n\n\n\n<p class=\"has-light-gray-background-color has-background\"><a href=\"https:\/\/willem.aandewiel.nl\/index.php\/2024\/08\/16\/arduino-to-platformio-project-conversion\/\">Here<\/a> you can find an English version of this post<\/p>\n\n\n\n<p>Deze vriend, een professionele software engineer, ging met mijn software aan de haal om de functionaliteit aan te passen aan zijn wensen en eisen. Maar door zijn ervaring heeft hij nooit aan de manier waarop je met de Arduino IDE software ontwikkelt kunnen wennen. Voor hem was het allemaal erg \u201con-natuurlijk\u201d.<\/p>\n\n\n\n<p>Op enig moment ontdekte hij Visual Studio Code en met die IDE in samenwerking met de \u201cPlatformIO\u201d extensie kon hij software voor zijn meet-en-regel-systemen ontwikkelen op een manier die voor hem w\u00e9l \u201cnatuurlijk\u201d was.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"621\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer-1024x621.png\" alt=\"\" class=\"wp-image-8016\" style=\"width:606px;height:auto\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer-1024x621.png 1024w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer-300x182.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer-768x466.png 768w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PIO_Explorer.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Ik heb ook naar Visual Studie Code met de PlatformIO extensie (vanaf nu gewoon \u201cPlatformIO\u201d genoemd) gekeken maar liep al snel vast door de vrij stijle leer curve.<\/p>\n\n\n\n<p>Uiteindelijk heb ik, voor nieuwe projecten, de overstap toch gemaakt en ben \u00e9rg enthousiast geworden. Ook omdat ik Visual Studio Code (VSC) nu niet alleen gebruik voor het ontwikkelen van software voor MCU\u2019s maar ook voor de ontwikkeling van Python en openSCAD programma\u2019s. Alles dus met \u00e9\u00e9n IDE (met verschillende \u201cextensies\u201d) wat de productiviteit ten goede komt omdat je niet steeds van IDE hoeft te wisselen.<\/p>\n\n\n\n<p>E\u00e9n van de grootste problemen die ik met de Arduino IDE en Arduino projecten heb, is dat het lastig is om vast te leggen welke versie van bibliotheken je voor een project gebruikt en wat voor type MCU met de daarbij horende instellingen je moet selecteren om een project te kunnen compileren en flashen. Omdat ik veel projecten op deze website publiceer en deze nagebouwd worden door meer- of minder ervaren makers blijkt toch iedere keer dat ik zaken niet goed (genoeg) heb beschreven en\/of dat makers niet het geduld hebben om alles goed te lezen. Maar een groter probleem is dat in de loop der tijd core software en bibliotheken \u00f3\u00f3k vernieuwd worden en dat core software opeens hele andere instellingen en mogelijkheden krijgt (die nu niet meer aansluiten bij mijn beschrijving) en dat nieuwere bibliotheken niet altijd compatibel zijn met de versie die ik voor het project heb gebruikt.<\/p>\n\n\n\n<p>En daar heeft PlatformIO een briljante oplossing voor door voor ieder project een &#8216;platformio.ini&#8217; bestand te gebruiken waarin al dit soort zaken vastgelegd zijn. Het platform (in Arduino taal de gebruikte core), het type board (NodeMCU, Arduino UNO, ATtiny85 enz.) en welke libraries gebruikt worden in een project ligt vast in het platformio.ini bestand waarbij je ook nog kunt opgeven dat je een specifieke versie van een library wilt gebruiken. Het \u201cplatformio.ini\u201d bestand is onderdeel van het hele project waarbij je ook nog eens niets zelf hoeft te installeren of uit te zoeken. Eenvoudig een project folder openen en compileren zorgt ervoor dat alle benodigde (externe) core-bestanden en bibliotheken met de goede versie worden gedownload (dat gaat overigens razend snel en hoeft alleen de eerste keer dat je een project compileert te gebeuren).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Voorbeeld van een &#8220;platformio.ini&#8221; bestand<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  ; PlatformIO Project Configuration File\n  ;\n  ;   Build options: build flags, source filter\n  ;   Upload options: custom upload port, speed and extra flags\n  ;   Library options: dependencies, extra library storages\n  ;   Advanced options: extra scripting\n  ;\n  ; Please visit documentation for the other options and examples\n  ; https:\/\/docs.platformio.org\/page\/projectconf.html\n\n  [platformio]\n  workspace_dir   = .pio.nosync\n  default_envs    = myBoard\n\n  [env:myBoard]\n  platform        = atmelavr\n  board           = uno\n  upload_protocol = usbtiny\n  framework       = arduino\n  monitor_speed   = 19200\n  upload_speed    = 19200\n  upload_port     = #select port like \"\/dev\/cu.usbserial-3224144\"\n  build_flags     = \n\t          -D DEBUG\n  lib_ldf_mode    = deep+\n  lib_deps = \n\t          marcoschwartz\/LiquidCrystal_I2C@^1.1.4\n\t          chris--a\/Keypad@^3.1.1\n            \n  monitor_filters =<\/pre>\n\n\n\n<p>Nu ik PlatformIO voor nieuwe projecten gebruik wil ik mijn bestaande Arduino projecten het liefst \u00f3\u00f3k omzetten naar de PlatformIO structuur. Maar dat blijkt minder eenvoudig dan je zou denken (of hopen).<\/p>\n\n\n\n<p>Er zijn op internet wel handleidingen die dit proces beschrijven, maar deze zijn vaak onvolledig en gaan bijna allemaal uit van een eenvoudig project met maar \u00e9\u00e9n \u2018.ino\u2019 bestand.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Ik dacht: dat moet makkelijker kunnen.<br><\/h3>\n\n\n\n<p>Om een Arduino project om te kunnen zetten naar een PlatformIO structuur is het belangrijk te begrijpen hoe de Arduino IDE \u201cwerkt\u201d en wat deze IDE doet om een project te compileren.<br>De Arduino IDE doet achter de schermen (of onder de motorkap) een aantal zaken met de &#8216;.ino&#8217; bestanden waar het project uit bestaat.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Samenvoegen van .ino Bestanden<\/h2>\n\n\n\n<p>De Arduino IDE begint het compilatieproces door alle \u2018.ino\u2019 bestanden in je project achter elkaar te plakken tot \u00e9\u00e9n groot gecombineerd bestand. Dit gebeurt in alfabetische volgorde van de bestandsnamen. Stel je voor dat je drie bestanden hebt: \u2018mijnProgramma.ino\u2019, \u2018sensor.ino\u2019 en \u2018display.ino\u2019. De IDE voegt deze samen in de volgorde \u2018display.ino\u2019, \u2018mijnProgramma.ino\u2019 en \u2018sensor.ino\u2019. Dit betekent dat de volgorde van de bestanden invloed kan hebben op het gedrag van je code, vooral als functies in verschillende bestanden elkaar aanroepen.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Aanmaken van Functieprototypes<\/h2>\n\n\n\n<p>Nadat de bestanden zijn samengevoegd, scant de Arduino IDE het gecombineerde bestand op zoek naar alle functies die je hebt gedefinieerd. Vervolgens maakt de IDE automatisch prototypes voor deze functies en zet deze bovenaan het gecombineerde bestand. Een functieprototype is een declaratie van een functie die aangeeft wat voor type waarde de functie teruggeeft en welke argumenten de functie verwacht, zonder de volledige functie-implementatie. Dit stelt de compiler in staat om functies aan te roepen die verderop in het bestand gedefinieerd zijn, wat normaal gesproken niet mogelijk zou zijn zonder prototypes (standaard kan in C of C++ een functie pas gebruikt worden als hij v\u00f3\u00f3r de aanroep gedefinieerd is).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Globale variabelen<\/h2>\n\n\n\n<p>Als je een variabele buiten een functie declareert (dus niet binnen de accolades &#8216;{}&#8217; van een functie), dan is, door het samenvoegen van alle \u2018.ino\u2019 bestanden door de Arduino IDE, deze variabele <strong>globaal<\/strong> en beschikbaar voor alle functies in alle samengevoegde \u2018.ino\u2019 bestanden. Bijvoorbeeld, een variabele \u2018int sensorValue;\u2019 die in \u2018sensor.ino\u2019 wordt gedeclareerd, kan zonder problemen worden gebruikt in \u2018mijnProgramma.ino\u2019 of \u2018display.ino\u2019.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Inclusie van Bibliotheken met &#8216;#include&#8217;<\/h2>\n\n\n\n<p>Bij het gebruik van externe bibliotheken in een Arduino-project moet je deze importeren met de &#8216;#include&#8217; directive. Als je een bibliotheek in \u00e9\u00e9n \u2018.ino\u2019 bestand importeert, geldt dit, na samenvoeging door de IDE, voor het hele gecombineerde bestand.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dubbele &#8216;#include&#8217; directives<\/h2>\n\n\n\n<p>Het is niet noodzakelijk, maar ook niet schadelijk, om dezelfde &#8216;#include&#8217; directive in meerdere &#8216;.ino&#8217; bestanden te plaatsen. De compiler zorgt ervoor dat een bibliotheek maar \u00e9\u00e9n keer wordt toegevoegd, zelfs als de &#8216;#include&#8217; directive, door het samenvoegen van alle \u2018.ino\u2019 bestanden, meerdere keren voorkomt. Dit komt doordat de meeste bibliotheken zichzelf beschermen tegen dubbele inclusie door middel van &#8216;#ifndef&#8217; en &#8216;#define&#8217; (zogenaamd \u2018Header Guards\u2019) directives in hun header bestanden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Compilatie als \u00e9\u00e9n Programma<\/h2>\n\n\n\n<p>Nu de bestanden zijn samengevoegd en de prototypes zijn aangemaakt, behandelt de IDE het resultaat als \u00e9\u00e9n enkel bestand. Dit betekent dat de code nu wordt gecompileerd alsof het een enkel \u2018.ino\u2019 bestand is. De compiler doorloopt de code, vertaalt deze naar machine-instructies en controleert op syntaxis- en semantische fouten. Omdat alles nu in \u00e9\u00e9n bestand staat waarbij alle functies als \u201cprototype\u201d aan het begin van het samengevoegde bestand staan, kunnen functies in verschillende bestanden probleemloos met elkaar communiceren, zonder dat de gebruiker zich zorgen hoeft te maken over de volgorde van de functie-definities.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">En hoe ziet een PlatformIO project er dan uit?<\/h1>\n\n\n\n<p>Als je een project start met PlatformIO, krijg je een gestructureerde map waarin je al je code, instellingen en andere bestanden kunt opslaan. Deze structuur helpt je om overzicht te houden, vooral als je project groter wordt.<br>De project folder bestaat minimaal uit een \u2018platformio.ini\u2019 bestand en twee folders waarin alle code staat. Deze folders zijn \u201csrc\u201d waar alle \u2018.c\u2019 en \u2018.cpp\u2019 bestanden van het project staan en \u201cinclude\u201d waarin alle header bestanden van het project staan.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Het &#8216;platformio.ini&#8217; bestand<\/h2>\n\n\n\n<p>Dit bestand is als de &#8220;gebruiksaanwijzing&#8221; voor je project. Hierin staat welke microcontroller je gebruikt, welke bibliotheken nodig zijn, en hoe alles geconfigureerd moet worden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">De &#8220;src&#8221; map<\/h2>\n\n\n\n<p>Dit is de plek waar je de belangrijkste code van je project bewaart. Hierin staan bestanden met de extensie \u2018.c\u2019 voor C code en \u2018.cpp\u2019 voor C++ code.<br>De naam &#8220;src&#8221; staat voor &#8220;source&#8221;, wat betekent dat dit de broncode van je project is.<br>Omdat PlatformIO niet, zoals de Arduino IDE doet, alle code bestanden achter elkaar zet is ieder \u2018.c\u2019 of \u2018.cpp\u2019 bestand een afzonderlijk object. Zonder speciale instructies weten deze zelfstandige objecten niets van elkaar.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">De &#8220;include&#8221; map<\/h2>\n\n\n\n<p>In deze map bewaar je bestanden met &#8220;voorbereidende&#8221; code, ook wel header-bestanden genoemd. Een header-bestand wordt meestal gebruikt om de \u201cinterface\u201d van je code tussen verschillende objecten te defini\u00ebren, vooral als je functies, variabelen of klassen in andere bestanden wilt gebruiken. Header bestanden hebben de extensie \u2018.h\u2019.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Voorbeeld van hoe zo&#8217;n project er in PlatformIO uitziet<\/h2>\n\n\n\n<p>Stel je voor dat je een project hebt genaamd &#8216;MyProject&#8217;. Dit is hoe de structuur er dan uit zou kunnen zien:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-medium\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/platformIO_structuur.png\"><img loading=\"lazy\" decoding=\"async\" width=\"272\" height=\"300\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/platformIO_structuur-272x300.png\" alt=\"\" class=\"wp-image-8002\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/platformIO_structuur-272x300.png 272w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/platformIO_structuur.png 742w\" sizes=\"auto, (max-width: 272px) 100vw, 272px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>&#8216;main.cpp&#8217; bevat de code van je project.<br>&#8216;my_header.h&#8217; is een header-bestand met code die je op meerdere plekken in je project kunt gebruiken.<br>&#8216;platformio.ini&#8217; is het bestand dat PlatformIO de instructies geeft over hoe het project moet worden gebouwd en uitgevoerd.<\/p>\n\n\n\n<p>Alles wat er in \u2018my_header.h\u2019 wordt gedefinieerd of vastgelegd komt beschikbaar of is van invloed op alle andere .c of .cpp bestanden die dit header bestand via de \u2018<code>#include \u201cmy_header.h\u201d<\/code>\u2019 invoegen.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Het conversie programma<\/h1>\n\n\n\n<p>Nu we weten wat de Arduino IDE doet om een complex project te compileren \u00e9n we weten hoe een project er in PlatformIO uit ziet moet het mogelijk zijn om hiervoor een automatisch conversie programma te schrijven. Ik zet op een rijtje welke stappen dit conversie programma moet doorlopen om deze taak uit te kunnen voeren.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Stap 1<\/h2>\n\n\n\n<p>In deze stap moet de directory structuur voor een PlatformIO project worden opgezet. Ik heb ervoor gekozen om in een Arduino project (waarvan de top-directory altijd dezelfde naam heeft als het \u201choofd\u201d .ino bestand) een nieuwe map \u201cPlatformIO\u201d aan te maken. Onder deze map komt een tweede map met de naam van het arduino project. Zie onderstaande plaatje van het originele Arduino project \u201cpulsGenerator\u201d:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"229\" height=\"100\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/pulsGeneratorArduino.png\" alt=\"\" class=\"wp-image-8000\" style=\"width:554px;height:auto\"\/><\/figure>\n<\/div>\n\n\n<p>Zoals je kunt zien bestaat dit project uit drie &#8216;.ino&#8217; bestanden. In de Arduino IDE ziet dat er zo uit:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/ArduinoIDE.png\"><img loading=\"lazy\" decoding=\"async\" width=\"878\" height=\"728\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/ArduinoIDE.png\" alt=\"\" class=\"wp-image-8001\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/ArduinoIDE.png 878w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/ArduinoIDE-300x249.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/ArduinoIDE-768x637.png 768w\" sizes=\"auto, (max-width: 878px) 100vw, 878px\" \/><\/a><\/figure>\n\n\n\n<p>Goed om te weten is dat de Arduino IDE alle bestanden die niet de extensie \u2018.ino\u2019, \u2018.c\u2019, \u2018.cpp\u2019 of \u2018.h\u2019 hebben negeert.<br>Het \u2018README.md\u2019 bestand die wel degelijk in de project directory staat wordt dus niet \u2018gezien\u2019 door de Arduino IDE. Hetzelfde geldt voor de map \u2018PlatformIO\u2019 die het conversie programma gaat aanmaken.<br>Na Stap 1 ziet de bestands structuur er zo uit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PlatformIO_mappen.png\"><img loading=\"lazy\" decoding=\"async\" width=\"276\" height=\"203\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/PlatformIO_mappen.png\" alt=\"\" class=\"wp-image-8003\" style=\"width:406px;height:auto\"\/><\/a><\/figure>\n<\/div>\n\n\n<ol class=\"wp-block-list\">\n<li>Dit is de genoemde PlatformIO directory (deze map en alle onderliggende mappen en bestanden zijn niet zichtbaar in de Arduino IDE)<\/li>\n\n\n\n<li>Dit is de PlatformIO project Folder<\/li>\n\n\n\n<li>De \u201csrc\u201d en \u201cinclude\u201d folder en een template voor het platformio.ini bestand<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Stap 2<\/h2>\n\n\n\n<p>In deze stap worden alle aanwezige \u2018.ino\u2019, \u2018.c\u2019 en \u2018.cpp\u2019 bestanden naar de \u201csrc\u201d map gekopieerd en worden eventueel aanwezige \u2018.h\u2019 bestanden naar de \u201cinclude\u201d map gekopieerd.<br>Nu worden alle globaal gedefinieerde variabelen, constant pointers, functie definities en \u201c#include\u201d statements in tabellen gezet. De in de &#8216;.ino&#8217; bestanden gevonden \u201c#include\u201d statements worden daar tot commentaar aangepast.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/#include &lt;Wire.h>                \/\/-- moved to arduinoGlue.h\n\/\/#include &lt;LiquidCrystal_I2C.h>   \/\/-- moved to arduinoGlue.h\n<\/pre>\n\n\n\n<p><br>In eventueel al aanwezige header bestanden worden Header Guards aangebracht (als die niet al aanwezig zijn).<br>Vervolgens worden alle gegevens uit de eerder aangemaakte tabellen in een nieuw \u201carduinoGlue.h\u201d bestand gestopt waarbij globale variabelen het voorvoegsel \u201cextern\u201d krijgen. Dit heeft hetzelfde effect als \u201cprototypes\u201d. De compiler weet dat zo\u2019n variabel \u2018ergens\u201d gedeclareerd gaat worden maar hoeft niet te weten w\u00e1\u00e1r die declaratie plaats gaat vinden. Dat is een taak die de \u201clinker\u201d gaat uitzoeken. Dit header bestand bevat nu dus alle gegevens voor de overige bestanden om foutloos te kunnen compileren.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#ifndef ARDUINOGLUE_H\n#define ARDUINOGLUE_H\n\n#define SETBIT(a,b)             ((a) |= _BV(b))\n#define CLEARBIT(a, b)          ((a) &amp;= ~_BV(b))\n#define SET_LOW(_port, _pin)    ((_port) &amp;= ~_BV(_pin))\n#define SET_HIGH(_port, _pin)   ((_port) |= _BV(_pin))\n  #define pinA        8     \/\/ PB0    \n  #define pinAbit     0     \/\/ PB0\n  #define pinB        9     \/\/ PB1   \n  #define pinBbit     1     \/\/ PB1\n  #define pinA       11     \/\/ PB3   \n  #define pinAbit     3     \/\/ PB3\n  #define pinB       12     \/\/ PB4   \n  #define pinBbit     4     \/\/ PB5\n#define POTMETER      A0     \/\/ PC0\n#define LED_PULSE_ON  A1\n#define LED_POTMETER  A2\n#define LED_SWEEPMODE A3\n#define _CLOCK    16000000\n#define _MAXFREQCHAR    20\n#define _HYSTERESIS      5\n\n\/\/-- dict_all_includes ---\n#include &lt;Wire.h>\n#include &lt;LiquidCrystal_I2C.h>\n#include &lt;Keypad.h>\n\n\/\/-- dict_global_variables ---\nextern int32_t         diffFrequency;                     \t\t\/\/-- from pulsGenerator\nextern int32_t         endSweepFreq;                      \t\t\/\/-- from pulsGenerator\nextern uint8_t         freqKeyPos;                        \t\t\/\/-- from pulsGenerator\nextern volatile int32_t frequency;                         \t\t\/\/-- from pulsGenerator\nextern char            inputKey;                          \t\t\/\/-- from pulsGenerator\nextern uint32_t        ledBuiltinTimer;                   \t\t\/\/-- from pulsGenerator\nextern int32_t         newFrequency;                      \t\t\/\/-- from pulsGenerator\nextern char            newInputChar[_MAXFREQCHAR];        \t\t\/\/-- from pulsGenerator\nextern uint16_t        newPotValue;                       \t\t\/\/-- from pulsGenerator\nextern uint16_t        potSaved;                          \t\t\/\/-- from pulsGenerator\nextern uint16_t        potValue;                          \t\t\/\/-- from pulsGenerator\nextern bool            potmeterActive;                    \t\t\/\/-- from pulsGenerator\nextern int32_t         startSweepFreq;                    \t\t\/\/-- from pulsGenerator\nextern float           stepFrequency;                     \t\t\/\/-- from pulsGenerator\nextern bool            sweepModeActive;                   \t\t\/\/-- from pulsGenerator\nextern uint32_t        sweepTime;                         \t\t\/\/-- from pulsGenerator\nextern uint32_t        sweepTimer;                        \t\t\/\/-- from pulsGenerator\nextern volatile int8_t togglePin;                         \t\t\/\/-- from pulsGenerator\n\n\/\/-- dict_prototypes ---\n\/\/-- from displayStuff.ino -----------\nvoid setupLCD();                                            \nvoid initLCD();                                             \nvoid updateLCD();                                           \nvoid easterLCD();                                           \n\/\/-- from pulsGenerator.ino -----------\nvoid explanation();                                         \nvoid readPotmeter();                                        \nvoid calculateSweep();                                      \nvoid sweep();                                               \n\/\/-- from timer1Stuff.ino -----------\nint32_t calculateTimer1(int32_t freqAsked, uint8_t &amp;newTCCR1B);\nvoid setupTimer1(int32_t newFrequency);                     \n\n#endif \/\/ ARDUINOGLUE_H\n<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Stap 3<\/h2>\n\n\n\n<p>In deze stap wordt voor alle &#8216;.ino&#8217; bestanden een header bestand aangemaakt voorzien van Header Guards en een \u2018#include \u201carduinoGlue.h\u201d\u2019 (dit gebeurt niet voor \u2018.c\u2019 en \u2018.cpp\u2019 bestanden omdat deze, als ze in het originele Arduino project gebruikt worden, al een \u2018.h\u2019 bestand moeten hebben).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Stap 4<\/h2>\n\n\n\n<p>In het \u201choofd-project\u201d bestand (in ons voorbeeld \u201cpulsGenerator.ino\u201d) wordt een \u201c#include\u201d statement voor alle andere header bestanden ingevoegd zodat de \u2018.cpp\u2019 objecten met dezelfde naam worden ingevoegd. In dit voorbeeld project zijn dat:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"false\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">#include \u201carduinoGlue.h\u201d\n#include \u201cdisplayStuff.h\u201d \/\/-- voor \u2018displayStuff.cpp\u2019\n#include \u201ctimer1Stuff.h\u201d  \/\/--voor \u2018timer1Stuff.cpp\u2019<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Stap 5<\/h2>\n\n\n\n<p>Nu worden alle &#8216;.ino&#8217; bestanden in de \u201csrc\u201d directory hernoemd tot &#8216;.cpp&#8217; bestanden.<br>Na de conversie ziet de directory structuur er zo uit:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/naConversie.png\"><img loading=\"lazy\" decoding=\"async\" width=\"305\" height=\"346\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/naConversie.png\" alt=\"\" class=\"wp-image-8006\" style=\"width:502px;height:auto\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/naConversie.png 305w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/naConversie-264x300.png 264w\" sizes=\"auto, (max-width: 305px) 100vw, 305px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\">Wat rest<\/h2>\n\n\n\n<p>Wat rest en niet geautomatiseerd kan worden is het aanpassen van het &#8216;platformio.ini&#8217; bestand.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"527\" src=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor-1024x527.png\" alt=\"\" class=\"wp-image-8017\" style=\"width:573px;height:auto\" srcset=\"https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor-1024x527.png 1024w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor-300x154.png 300w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor-768x395.png 768w, https:\/\/willem.aandewiel.nl\/wp-content\/uploads\/2024\/08\/RunningConvertor.png 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<h1 class=\"wp-block-heading\">Waar kun je het conversie programma vinden?<\/h1>\n\n\n\n<p>In <a href=\"https:\/\/github.com\/mrWheel\/arduinoIDE2platformIO-convertor\" target=\"_blank\" rel=\"noreferrer noopener\">deze repo<\/a> staat het \u201c<a href=\"https:\/\/github.com\/mrWheel\/arduinoIDE2platformIO-convertor\" target=\"_blank\" rel=\"noreferrer noopener\">arduinoIDE2platformIO.py<\/a>\u201d conversie programma. In deze repo staan in de map \u201ctestproject\u201d twee voorbeeld Arduino projecten die je, als test, met dit programma kunt omzetten in een PlatformIO project.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">En wat als je van een PlatformIO project een Arduino IDE versie wilt maken?<\/h1>\n\n\n\n<p>Die conversie is een stuk eenvoudiger. In <a href=\"https:\/\/github.com\/mrWheel\/platformIO2arduinoIDE-convertor\/tree\/main\" target=\"_blank\" rel=\"noreferrer noopener\">deze repo<\/a> vind je het &#8220;<a href=\"https:\/\/github.com\/mrWheel\/platformIO2arduinoIDE-convertor\/tree\/main\" target=\"_blank\" rel=\"noreferrer noopener\">platformIO2arduinoIDE.py<\/a>&#8221; programma die dit automatisch voor je doet!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ ] Voor een vriend heb ik hardware ontwikkeld om de vloerverwarming van zijn huis effectiever en effici\u00ebnter te regelen. Om deze hardware te kunnen testen schreef ik software met de Arduino IDE. Voor mij de enige manier die ik &hellip; <a href=\"https:\/\/willem.aandewiel.nl\/index.php\/2024\/08\/14\/conversie-arduino-naar-platformio-project\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":8017,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[144,2,3,143,15],"tags":[176,173,174,175,172],"class_list":["post-7998","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aandewiel","category-arduino","category-computer","category-firmware","category-scripts","tag-convertor","tag-platformio","tag-python","tag-python3","tag-vscode"],"views":2865,"_links":{"self":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/7998","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/comments?post=7998"}],"version-history":[{"count":23,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/7998\/revisions"}],"predecessor-version":[{"id":8161,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/posts\/7998\/revisions\/8161"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/media\/8017"}],"wp:attachment":[{"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/media?parent=7998"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/categories?post=7998"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/willem.aandewiel.nl\/index.php\/wp-json\/wp\/v2\/tags?post=7998"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}