{"id":5115,"date":"2022-11-10T20:56:51","date_gmt":"2022-11-10T19:56:51","guid":{"rendered":"https:\/\/www.pschatzmann.ch\/home\/?p=5115"},"modified":"2024-02-29T03:53:43","modified_gmt":"2024-02-29T02:53:43","slug":"espeak-ng-the-difficult-journey-to-an-arduino-library","status":"publish","type":"post","link":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/","title":{"rendered":"ESpeak-NG: The difficult journey to an Arduino Library"},"content":{"rendered":"<p>I converted eSpeak NG to an Arduino Library.<\/p>\n<p>The eSpeak NG is a compact open source software text-to-speech synthesizer for Linux, Windows, Android and other operating systems. It supports more than 100 languages and accents. It is based on the eSpeak engine created by Jonathan Duddington.<\/p>\n<p>eSpeak NG uses a &#8220;formant synthesis&#8221; method. This allows many languages to be provided in a small size. The speech is clear, and can be used at high speeds, but is not as natural or smooth as larger synthesizers which are based on human speech recordings. It also supports Klatt formant synthesis, and the ability to use MBROLA as backend speech synthesizer.<\/p>\n<h2>Overview<\/h2>\n<p>The first step to convert the espeak-ng project to an <strong>Arduino library<\/strong> was quite easy. I just needed to move the files into the <strong>src directory<\/strong>, so that they can be found by Arduino and delete some implementation files, that were disturbing.<\/p>\n<p>The project was compiling now, but nothing was working yet. There were the following <strong>major challenges<\/strong>:<\/p>\n<ul>\n<li>The project is reading and processing an undefined number of <strong>configuration files<\/strong> with the C API. <\/li>\n<li>For the <strong>audio output<\/strong> the project was using <strong>pcaudiolib<\/strong>.<\/li>\n<li>The program was crashing with <strong>memory errors<\/strong><\/li>\n<li>The C++ API was not producing any audio output<\/li>\n<\/ul>\n<h2>Handling The Audio Output<\/h2>\n<p>This was quite straight forward. All I needed to do was to provide some pcaudiolib implementation. As a first thought I planned to integrate the AudioTools library, but I did not like the idea of having this specific dependency. In the end I decided to provide an API which is based on <strong>Arduino Streams<\/strong>. We can register any Arduino Stream as output and can query the audio parameters:<\/p>\n<p>The relevant new methods are:<\/p>\n<pre><code>  audio_info espeak_info = espeak_get_audio_info();\n  espeak_set_audio_output(&amp;stream);\n\n<\/code><\/pre>\n<h2>Handling Configuration Files<\/h2>\n<p>The ESP32 provides a <strong>virtual file system<\/strong>, so we can use the regular C file API together e.g. with an SD card. However I soon realized that the data is loaded into RAM and it is just too big!<\/p>\n<p>Here is the minimum required data for the <strong>english language<\/strong>:<\/p>\n<table>\n<thead>\n<tr>\n<th>size<\/th>\n<th>file<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>166916<\/td>\n<td>en_dict<\/td>\n<\/tr>\n<tr>\n<td>2040<\/td>\n<td>intonations<\/td>\n<\/tr>\n<tr>\n<td>140<\/td>\n<td>lang\/en<\/td>\n<\/tr>\n<tr>\n<td>550424<\/td>\n<td>phondata<\/td>\n<\/tr>\n<tr>\n<td>39062<\/td>\n<td>phonindex<\/td>\n<\/tr>\n<tr>\n<td>55764<\/td>\n<td>phontab<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The best place to store this constant information is in PROGMEM. I therefore created a <strong>new <a href=\"https:\/\/github.com\/pschatzmann\/arduino-posix-fs\">arduino-posix-fs<\/a> project<\/strong> with the goal to provide an API to <strong>access the PROGMEM data with the regular file operations<\/strong>.<\/p>\n<p>Here is the syntax to make the data available as files:<\/p>\n<pre><code>  file_systems::FileSystemMemory fsm(\"\/mem\"); \/\/ File system data in PROGMEM\n  \/\/ setup min file system\n  fsm.add(\"\/mem\/data\/phontab\", espeak_ng_data_phontab,espeak_ng_data_phontab_len);\n  fsm.add(\"\/mem\/data\/phonindex\", espeak_ng_data_phonindex,espeak_ng_data_phonindex_len);\n  fsm.add(\"\/mem\/data\/phondata\", espeak_ng_data_phondata,espeak_ng_data_phondata_len);\n  fsm.add(\"\/mem\/data\/intonations\", espeak_ng_data_intonations,espeak_ng_data_intonations_len);\n  \/\/ add language specific files\n  fsm.add(\"\/mem\/data\/en_dict\", espeak_ng_data_en_dict,espeak_ng_data_en_dict_len);\n  fsm.add(\"\/mem\/data\/lang\/en\", espeak_ng_data_lang_gmw_en, espeak_ng_data_lang_gmw_en_len);\n<\/code><\/pre>\n<p>The espeak-ng application then accesses this information via regular file operations or by the preferred way with mem_map() which provides a pointer to the data:<\/p>\n<pre><code>size_t result_size;\nuint8_t* mem_map(\"\/mem\/data\/phontab\", &amp;result_size);\n<\/code><\/pre>\n<h2>Program Crashes<\/h2>\n<p>I could identify the root cause of the crashes to the use of <strong>big data structures on the stack<\/strong>. So I needed to perform quite some optimizations that are activated with #define ESPEAK_STACK_HACK 1 in config.h<br \/>\nThe standard workaround was to <strong>move the big data structures from the stack to the heap<\/strong>.<\/p>\n<p>I also changed the provided fixed arrays as const, to make sure that they are stored in PROGMEM.<\/p>\n<h2>The API<\/h2>\n<p>ESpeak provides a <a href=\"https:\/\/pschatzmann.github.io\/arduino-espeak-ng\/docs\/html\/speak__lib_8h.html\">Functional API<\/a>, so I decided to add a simple <a href=\"https:\/\/pschatzmann.github.io\/arduino-espeak-ng\/docs\/html\/class_e_speak.html\">C++ API<\/a> on top of it.<\/p>\n<p>Here is the <a href=\"https:\/\/github.com\/pschatzmann\/arduino-espeak-ng\/blob\/main\/examples\/espeak-arduino\/espeak-arduino.ino\">Arduino Example<\/a> that is using my <strong>Arduino C++ API<\/strong>.<\/p>\n<p>Here as well, I was running into some really strange issues: On the Desktop and on PlatformIO the example was working as expected, but <strong>only in Arduino it did not work<\/strong> and did not produce any audio output. It was pretty nasty to resolve this since I needed to add plenty of println() statements to find which method was causing the issue: It turned out that the espeak-ng FindReplacementChars() method was running into an endless loop.<\/p>\n<p>I still don&#8217;t know the root cause, but I added some additional break logic to prevent the issue.<\/p>\n<h2>Source Code and Further Information<\/h2>\n<p>You can find the <a href=\"https:\/\/github.com\/pschatzmann\/arduino-espeak-ng\">source code on Github<\/a>. If you plan to use this library, please read the README.md of the project.<\/p>\n<h2>Conclusion<\/h2>\n<p>The undertaking turned out to be <strong>much more difficult than initially thought<\/strong>, but I am <strong>happy<\/strong> that it is finally <strong>working now<\/strong>&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I converted eSpeak NG to an Arduino Library. The eSpeak NG is a compact open source software text-to-speech synthesizer for Linux, Windows, Android and other operating systems. It supports more than 100 languages and accents. It is based on the eSpeak engine created by Jonathan Duddington. eSpeak NG uses a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":5116,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[20,22,35],"tags":[27],"class_list":["post-5115","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-machine-sound","category-text-to-speech","tag-tts"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann\" \/>\n<meta property=\"og:description\" content=\"I converted eSpeak NG to an Arduino Library. The eSpeak NG is a compact open source software text-to-speech synthesizer for Linux, Windows, Android and other operating systems. It supports more than 100 languages and accents. It is based on the eSpeak engine created by Jonathan Duddington. eSpeak NG uses a [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/\" \/>\n<meta property=\"og:site_name\" content=\"Phil Schatzmann\" \/>\n<meta property=\"article:published_time\" content=\"2022-11-10T19:56:51+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-29T02:53:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png\" \/>\n\t<meta property=\"og:image:width\" content=\"512\" \/>\n\t<meta property=\"og:image:height\" content=\"512\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"pschatzmann\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"pschatzmann\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/\"},\"author\":{\"name\":\"pschatzmann\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"headline\":\"ESpeak-NG: The difficult journey to an Arduino Library\",\"datePublished\":\"2022-11-10T19:56:51+00:00\",\"dateModified\":\"2024-02-29T02:53:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/\"},\"wordCount\":679,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/espeak.png\",\"keywords\":[\"TTS\"],\"articleSection\":[\"Arduino\",\"Machine Sound\",\"Text To Speech\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/\",\"name\":\"ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/espeak.png\",\"datePublished\":\"2022-11-10T19:56:51+00:00\",\"dateModified\":\"2024-02-29T02:53:43+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/espeak.png\",\"contentUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/11\\\/espeak.png\",\"width\":512,\"height\":512},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2022\\\/11\\\/10\\\/espeak-ng-the-difficult-journey-to-an-arduino-library\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"ESpeak-NG: The difficult journey to an Arduino Library\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#website\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/\",\"name\":\"Phil Schatzmann Consulting\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\",\"name\":\"pschatzmann\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"contentUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\",\"width\":305,\"height\":305,\"caption\":\"pschatzmann\"},\"logo\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2022\\\/08\\\/pschatzmann.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/","og_locale":"en_US","og_type":"article","og_title":"ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann","og_description":"I converted eSpeak NG to an Arduino Library. The eSpeak NG is a compact open source software text-to-speech synthesizer for Linux, Windows, Android and other operating systems. It supports more than 100 languages and accents. It is based on the eSpeak engine created by Jonathan Duddington. eSpeak NG uses a [&hellip;]","og_url":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/","og_site_name":"Phil Schatzmann","article_published_time":"2022-11-10T19:56:51+00:00","article_modified_time":"2024-02-29T02:53:43+00:00","og_image":[{"width":512,"height":512,"url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png","type":"image\/png"}],"author":"pschatzmann","twitter_card":"summary_large_image","twitter_misc":{"Written by":"pschatzmann","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#article","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/"},"author":{"name":"pschatzmann","@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"headline":"ESpeak-NG: The difficult journey to an Arduino Library","datePublished":"2022-11-10T19:56:51+00:00","dateModified":"2024-02-29T02:53:43+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/"},"wordCount":679,"commentCount":0,"publisher":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png","keywords":["TTS"],"articleSection":["Arduino","Machine Sound","Text To Speech"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/","url":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/","name":"ESpeak-NG: The difficult journey to an Arduino Library - Phil Schatzmann","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#primaryimage"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png","datePublished":"2022-11-10T19:56:51+00:00","dateModified":"2024-02-29T02:53:43+00:00","breadcrumb":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#primaryimage","url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png","contentUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/11\/espeak.png","width":512,"height":512},{"@type":"BreadcrumbList","@id":"https:\/\/www.pschatzmann.ch\/home\/2022\/11\/10\/espeak-ng-the-difficult-journey-to-an-arduino-library\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pschatzmann.ch\/home\/"},{"@type":"ListItem","position":2,"name":"ESpeak-NG: The difficult journey to an Arduino Library"}]},{"@type":"WebSite","@id":"https:\/\/www.pschatzmann.ch\/home\/#website","url":"https:\/\/www.pschatzmann.ch\/home\/","name":"Phil Schatzmann Consulting","description":"","publisher":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.pschatzmann.ch\/home\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1","name":"pschatzmann","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","contentUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png","width":305,"height":305,"caption":"pschatzmann"},"logo":{"@id":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2022\/08\/pschatzmann.png"}}]}},"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/5115","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/comments?post=5115"}],"version-history":[{"count":6,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/5115\/revisions"}],"predecessor-version":[{"id":5122,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/5115\/revisions\/5122"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media\/5116"}],"wp:attachment":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media?parent=5115"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/categories?post=5115"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/tags?post=5115"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}