{"id":7187,"date":"2026-10-27T11:12:03","date_gmt":"2026-10-27T10:12:03","guid":{"rendered":"https:\/\/www.pschatzmann.ch\/home\/?p=7187"},"modified":"2026-10-22T11:49:48","modified_gmt":"2026-10-22T09:49:48","slug":"tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept","status":"publish","type":"post","link":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/","title":{"rendered":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept"},"content":{"rendered":"<p>If you look for <strong>speech recognition examples for microcontrollers,<\/strong> you almost always end up with wake word detection or keyword spotting: the <code>micro_speech<\/code> example of<\/p>\n<ul>\n<li><strong>TensorFlow Lite Micro<\/strong>, which recognizes &#8220;yes&#8221; and &#8220;no&#8221;;<\/li>\n<li><strong>Espressif&#8217;s ESP-SR<\/strong> with WakeNet for the wake word and MultiNet for a list of commands;<\/li>\n<li>keyword spotting models trained with <strong>Edge Impulse<\/strong>; or<\/li>\n<li>Picovoice&#8217;s <strong>Porcupine and Rhino<\/strong>.<\/li>\n<\/ul>\n<p>They work well for what they do, but they all classify a <strong>small, fixed set of words or phrases<\/strong> that is decided before the model is built. None of them turns arbitrary speech into text.<\/p>\n<p>After <a href=\"https:\/\/github.com\/pschatzmann\/TinyTTS\">TinyTTS<\/a> taught my microcontrollers to speak, the obvious next question was: can they also listen \u2013 really listen? Not &#8220;detect a wake word&#8221; or &#8220;recognize ten fixed commands&#8221;, but turn <strong>free speech into text, with a vocabulary of tens of thousands of words<\/strong>, completely offline, with hand-written C++ and without TensorFlow Lite or any other inference runtime.<\/p>\n<p><a href=\"https:\/\/github.com\/pschatzmann\/TinySTT\">TinySTT<\/a> is the answer I came up with. It is a <strong>proof of concept<\/strong>, and this post describes what works, what does not (yet), and what I learned on the way.<\/p>\n<h2 id=\"the-idea-split-the-problem-in-two\">The idea: split the problem in two<\/h2>\n<p>Speech recognition on a big machine is usually one large neural network that goes straight from audio to text. That does not fit into a microcontroller. So TinySTT splits the problem into two independent stages:<\/p>\n<ol>\n<li><strong>Speech \u2192 Phonemes:<\/strong> log-mel features (computed with the FFT of <a href=\"https:\/\/github.com\/pschatzmann\/arduino-audio-tools\">arduino-audio-tools<\/a>),<br \/>\nthen a small streaming acoustic model \u2013 a convolution and two GRU layers with 0.9 M parameters \u2013 that outputs phoneme probabilities every 30 ms.<\/li>\n<li><strong>Phonemes \u2192 Text:<\/strong> a beam search that only follows phoneme sequences that form words of a pronunciation dictionary, scored by a language model or by a command grammar such as <code>turn (on | off) the (light | fan)<\/code>.<\/li>\n<\/ol>\n<p>The two stages only exchange small phoneme frames (16 bytes) through a lock-free single-producer\/single-consumer queue. This has a nice side effect: they can run in one loop, <strong>on the two cores of an ESP32<\/strong>, or on <strong>two different devices<\/strong> connected by a serial line, UDP or ESP-NOW. The bandwidth between them is tiny: near-certain silence is merged into run-length messages, which cuts the traffic by a factor of 5\u201310.<\/p>\n<p>In a sketch, <code>TinySTT<\/code> is just another audio-tools <code>AudioOutput<\/code>: you copy the microphone data into it with a <code>StreamCopy<\/code>, and it prints each recognized utterance as a line to <code>Serial<\/code>.<\/p>\n<h2 id=\"making-it-fast-enough\">Making it fast enough<\/h2>\n<p>The first version was plain float C++ \u2013 and on an ESP32-S3 it needed 4.7 times longer than real time for the acoustic model alone. These were the steps that brought it below real time:<\/p>\n<table>\n<thead>\n<tr>\n<th>Step (ESP32-S3)<\/th>\n<th align=\"right\">Real-time factor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>float32 weights in flash<\/td>\n<td align=\"right\">4.73<\/td>\n<\/tr>\n<tr>\n<td>int8 weights<\/td>\n<td align=\"right\">2.64<\/td>\n<\/tr>\n<tr>\n<td>+ int8 activations and SIMD dot products<\/td>\n<td align=\"right\">1.26<\/td>\n<\/tr>\n<tr>\n<td>+ weights copied to PSRAM<\/td>\n<td align=\"right\">0.65<\/td>\n<\/tr>\n<tr>\n<td>+ the most used matrix in internal RAM<\/td>\n<td align=\"right\">0.55<\/td>\n<\/tr>\n<tr>\n<td>+ 4 frames computed per pass (batching)<\/td>\n<td align=\"right\">0.35<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>The surprise was that <strong>the S3 is memory bound, not compute bound<\/strong>. Once<br \/>\nSIMD is used, an int8 matrix-vector product takes 7.3 ms with the weights in<br \/>\nflash, 3.3 ms in PSRAM and 0.31 ms in internal RAM. Where the weights live<br \/>\nand how often they are read mattered more than the arithmetic. Batching four<br \/>\noutput frames reads the large matrices once instead of four times, at the<br \/>\ncost of 90 ms latency.<\/p>\n<p>Each platform got its own int8 dot product: Espressif&#8217;s esp-nn assembler on<br \/>\nthe ESP32-S3, my own PIE SIMD kernel on the ESP32-P4 (0.26 ms instead of<br \/>\n2.5 ms for a 768\u00d7256 matrix), the Cortex-M33 DSP instructions on the RP2350<br \/>\nand NEON on the Raspberry Pi. All of them are bit-identical to the plain C++<br \/>\nreference, which the tests check.<\/p>\n<p>The result for speech \u2192 phonemes, on one core:<\/p>\n<table>\n<thead>\n<tr>\n<th>Device<\/th>\n<th align=\"right\">Real-time factor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>ESP32-S3 (240 MHz)<\/td>\n<td align=\"right\">0.43<\/td>\n<\/tr>\n<tr>\n<td>ESP32-P4 (400 MHz)<\/td>\n<td align=\"right\">0.16<\/td>\n<\/tr>\n<tr>\n<td>RP2350 (150 MHz, with PSRAM)<\/td>\n<td align=\"right\">0.92<\/td>\n<\/tr>\n<tr>\n<td>Raspberry Pi 4<\/td>\n<td align=\"right\">0.016<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The decoder needs only a few percent on top. Even the RP2350 keeps up with<br \/>\nreal time, although only just, and only with careful memory placement.<\/p>\n<h2 id=\"training-the-acoustic-model\">Training the acoustic model<\/h2>\n<p>The acoustic model is trained with PyTorch on <a href=\"https:\/\/www.openslr.org\/12\">LibriSpeech<\/a>, using a free Kaggle GPU. The first model used 100 hours of audio and gave a word error rate (WER) of 36 % on LibriSpeech test-clean. Three changes brought it down to <strong>26 %<\/strong>:<\/p>\n<ul>\n<li><strong>A wider beam<\/strong> in the decoder (36 % \u2192 33 %): cheap, because the decoder is only a small part of the computation.<\/li>\n<li><strong>More and better training data<\/strong> (\u2192 30 %): 460 instead of 100 hours, and pronunciations from the LibriSpeech lexicon: only 7 % of the utterances are now skipped because a word is missing from the dictionary, instead of 38 %.<\/li>\n<li><strong>A larger vocabulary and language model<\/strong> (\u2192 26 %): 50,000 words and a bigram from the 800-million-word LibriSpeech text corpus. This model is9.5 MB, which an ESP32-S3 or ESP32-P4 handles easily.<\/li>\n<\/ul>\n<p>I also tried rescoring the best hypotheses with a trigram from an SD card \u2013 it improved the result by only 0.8 points, so I dropped the idea.<\/p>\n<p>Training on Kaggle was its own adventure: runs that sat in the queue for hours, a run that showed no log at all, and a first epoch on 460 hours that took 2\u00bc hours. In the end the training script checks its time budget during each epoch, so a run always finishes with an exported model before Kaggle&#8217;s 12-hour limit.<\/p>\n<h2 id=\"the-bugs-that-real-hardware-finds\">The bugs that real hardware finds<\/h2>\n<p>Most of the code was developed and tested on the desktop, with the <a href=\"https:\/\/github.com\/pschatzmann\/Arduino-Emulator\">Arduino-Emulator<\/a>. That<br \/>\nworks remarkably well \u2013 but some bugs only show up on real hardware, and they were the most instructive part of the project:<\/p>\n<ul>\n<li><strong>The Hann window<\/strong> in audio-tools used 0.54 instead of 0.5. Harmless for most uses, but the trained model depends on the exact features, so I fixed it upstream and retrained.<\/li>\n<li><strong>A decoder history that grew with every word<\/strong> used 100 KB of RAM for a 10-second utterance. Fine on a desktop, a crash on an RP2350. It now only keeps what the beam still needs: about 30 KB.<\/li>\n<li><strong>A race between the two cores:<\/strong> suspending a FreeRTOS task on the other core can return before that core has actually stopped it. The ESP32-P4 crashed on every boot \u2013 but only with a 10 MB program, because the larger image changed the timing.<\/li>\n<li><strong>The task watchdog:<\/strong> a decoder that falls behind never yields and starves the idle task. Easy to fix, once you know.<\/li>\n<li><strong>A WAV decoder<\/strong> that dropped the audio arriving in the same write as the header, and a channel converter that silently wrote nothing when used as an output \u2013 both fixed in audio-tools.<\/li>\n<\/ul>\n<h2 id=\"shipping-the-model-inside-the-program\">Shipping the model inside the program<\/h2>\n<p>A model is a 3 to 10 MB file. TinySTT can load it from a file system, map it from a flash partition, download it over Wi-Fi to an SD card \u2013 or compile it directly into the program. For the last option I first generated C arrays, which produced 29 MB of source code and very slow builds. The assembler directive <code>.incbin<\/code> does the same in seconds: it copies the file into the read-only data section at compile time.<\/p>\n<p>The tricky part was making it portable. The ESP32-S3 assembler ignores the include paths, so a relative path does not work. The trick that works with every toolchain I tried: the preprocessor replaces <code>__FILE__<\/code> with the absolute path of the assembler file, and a small assembler macro appends<code>.bin<\/code> \u2013 so the model file sits right next to it, wherever the library is installed. Sketches that do not use a model do not grow, because the linker drops sections that nobody references.<\/p>\n<h2 id=\"where-it-stands\">Where it stands<\/h2>\n<p>TinySTT shows that speech-to-text is possible on a microcontroller, with hand-written C++, faster than real time:<\/p>\n<ul>\n<li><strong>The split works.<\/strong> One loop, two cores or two devices give exactly the same text, and every platform produces the same transcripts.<\/li>\n<li><strong>Microcontrollers are fast enough<\/strong> \u2013 with int8 everywhere and with attention to where the weights are stored.<\/li>\n<li><strong>Accuracy is the limit.<\/strong> A word error rate of 26 % on read English speech is usable for voice commands, especially with a grammar, but not for reliable dictation. The training was stopped by the time budget while the error rate was still falling, so more training is the obvious next step, followed by a larger acoustic model on the faster chips.<\/li>\n<\/ul>\n<p>It is a proof of concept, not a product \u2013 but a proof that the concept works. The code, the trained models, the Kaggle notebook and all measurements are on <a href=\"https:\/\/github.com\/pschatzmann\/TinySTT\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you look for speech recognition examples for microcontrollers, you almost always end up with wake word detection or keyword spotting: the micro_speech example of TensorFlow Lite Micro, which recognizes &#8220;yes&#8221; and &#8220;no&#8221;; Espressif&#8217;s ESP-SR with WakeNet for the wake word and MultiNet for a list of commands; keyword spotting [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":7194,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","_exactmetrics_skip_tracking":false,"footnotes":""},"categories":[20,35],"tags":[27],"class_list":["post-7187","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino","category-text-to-speech","tag-tts"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - 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\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - Phil Schatzmann\" \/>\n<meta property=\"og:description\" content=\"If you look for speech recognition examples for microcontrollers, you almost always end up with wake word detection or keyword spotting: the micro_speech example of TensorFlow Lite Micro, which recognizes &#8220;yes&#8221; and &#8220;no&#8221;; Espressif&#8217;s ESP-SR with WakeNet for the wake word and MultiNet for a list of commands; keyword spotting [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/\" \/>\n<meta property=\"og:site_name\" content=\"Phil Schatzmann\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-27T10:12:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1254\" \/>\n\t<meta property=\"og:image:height\" content=\"1254\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\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=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/\"},\"author\":{\"name\":\"pschatzmann\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"headline\":\"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept\",\"datePublished\":\"2026-10-27T10:12:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/\"},\"wordCount\":1354,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#\\\/schema\\\/person\\\/73a53638a4e34e8373405fd737dac9b1\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/STT.jpg\",\"keywords\":[\"TTS\"],\"articleSection\":[\"Arduino\",\"Text To Speech\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/\",\"name\":\"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - Phil Schatzmann\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/STT.jpg\",\"datePublished\":\"2026-10-27T10:12:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/STT.jpg\",\"contentUrl\":\"https:\\\/\\\/www.pschatzmann.ch\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/STT.jpg\",\"width\":1254,\"height\":1254},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/2026\\\/10\\\/27\\\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.pschatzmann.ch\\\/home\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept\"}]},{\"@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":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - 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\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/","og_locale":"en_US","og_type":"article","og_title":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - Phil Schatzmann","og_description":"If you look for speech recognition examples for microcontrollers, you almost always end up with wake word detection or keyword spotting: the micro_speech example of TensorFlow Lite Micro, which recognizes &#8220;yes&#8221; and &#8220;no&#8221;; Espressif&#8217;s ESP-SR with WakeNet for the wake word and MultiNet for a list of commands; keyword spotting [&hellip;]","og_url":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/","og_site_name":"Phil Schatzmann","article_published_time":"2026-10-27T10:12:03+00:00","og_image":[{"width":1254,"height":1254,"url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg","type":"image\/jpeg"}],"author":"pschatzmann","twitter_card":"summary_large_image","twitter_misc":{"Written by":"pschatzmann","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#article","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/"},"author":{"name":"pschatzmann","@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"headline":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept","datePublished":"2026-10-27T10:12:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/"},"wordCount":1354,"commentCount":0,"publisher":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#\/schema\/person\/73a53638a4e34e8373405fd737dac9b1"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg","keywords":["TTS"],"articleSection":["Arduino","Text To Speech"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/","url":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/","name":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept - Phil Schatzmann","isPartOf":{"@id":"https:\/\/www.pschatzmann.ch\/home\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#primaryimage"},"image":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#primaryimage"},"thumbnailUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg","datePublished":"2026-10-27T10:12:03+00:00","breadcrumb":{"@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#primaryimage","url":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg","contentUrl":"https:\/\/www.pschatzmann.ch\/wp-content\/uploads\/2026\/10\/STT.jpg","width":1254,"height":1254},{"@type":"BreadcrumbList","@id":"https:\/\/www.pschatzmann.ch\/home\/2026\/10\/27\/tinystt-speech-to-text-on-a-microcontroller-a-proof-of-concept\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.pschatzmann.ch\/home\/"},{"@type":"ListItem","position":2,"name":"TinySTT: Speech-to-Text on a Microcontroller \u2013 a Proof of Concept"}]},{"@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\/7187","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=7187"}],"version-history":[{"count":9,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/7187\/revisions"}],"predecessor-version":[{"id":7197,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/posts\/7187\/revisions\/7197"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media\/7194"}],"wp:attachment":[{"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/media?parent=7187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/categories?post=7187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pschatzmann.ch\/home\/wp-json\/wp\/v2\/tags?post=7187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}