<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[luvsheth.com]]></title><description><![CDATA[I am a mechatronics engineer that works on consumer electronics products for my full time job. When I’m not working I tend to experiment with mini-projects, some of which I write about here.]]></description><link>https://luvsheth.com</link><image><url>https://substackcdn.com/image/fetch/$s_!0k_Y!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e6d77f-d635-45a4-928a-cd954373baa4_66x66.png</url><title>luvsheth.com</title><link>https://luvsheth.com</link></image><generator>Substack</generator><lastBuildDate>Wed, 22 Apr 2026 08:56:00 GMT</lastBuildDate><atom:link href="https://luvsheth.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Luv Sheth]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[luvsheth@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[luvsheth@substack.com]]></itunes:email><itunes:name><![CDATA[Luv Sheth]]></itunes:name></itunes:owner><itunes:author><![CDATA[Luv Sheth]]></itunes:author><googleplay:owner><![CDATA[luvsheth@substack.com]]></googleplay:owner><googleplay:email><![CDATA[luvsheth@substack.com]]></googleplay:email><googleplay:author><![CDATA[Luv Sheth]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[3D Printed Candle Mold]]></title><description><![CDATA[Observations from printing and casting candles with 3D printed molds]]></description><link>https://luvsheth.com/p/3d-printed-candle-mold</link><guid isPermaLink="false">https://luvsheth.com/p/3d-printed-candle-mold</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sat, 14 Feb 2026 12:04:59 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/075d9240-f0af-489c-be9c-9948960d4a97_6164x4096.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The goal here was to design and make custom candles using 3D printed molds. I&#8217;ll share my setup and key learnings that I didn&#8217;t find elsewhere.</p><h1><strong>Setup</strong></h1><ul><li><p><strong>What I want</strong>: I wanted two-tone candles with the tones separated horizontally rather than vertically. This required a two-part overmolding process: mold and make one candle, then insert it into a second mold and pour the second candle around it.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!gT-1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!gT-1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 424w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 848w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!gT-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg" width="352" height="469.25274725274727" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1941,&quot;width&quot;:1456,&quot;resizeWidth&quot;:352,&quot;bytes&quot;:6018966,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187813629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!gT-1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 424w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 848w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!gT-1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265cbcf-f8fb-481b-b86e-12732da5a81c_3072x4096.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Mold Design</strong>: I first designed the candle shape in 3D, then designed the mold using that shape. The mold consists of a cavity and a sealing pin. Once the wax sets, the sealing pin is removed and an ejector pin pushes the candle out. </p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FA6k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FA6k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 424w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 848w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 1272w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FA6k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png" width="1130" height="430" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:430,&quot;width&quot;:1130,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:144445,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187813629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FA6k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 424w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 848w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 1272w, https://substackcdn.com/image/fetch/$s_!FA6k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8e3de8e8-c8ed-46eb-a7f8-4751bcae1431_1130x430.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Sealing Pin</strong>: In practice, I left a bit of space and used Teflon tape around the sealing pin because a plastic-to-plastic hard seal would be less reliable and harder to remove. </p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bnfn!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bnfn!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 424w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 848w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 1272w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bnfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png" width="1456" height="537" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:537,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4414639,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187813629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bnfn!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 424w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 848w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 1272w, https://substackcdn.com/image/fetch/$s_!bnfn!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3b61be2e-7d85-4322-a199-dedbf87b2335_3619x1335.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Sealing Pin Shape</strong>: Use a circular-ish sealing pin shape - complex shapes are much harder to seal with Teflon tape. It doesn&#8217;t have to be a perfect circle; the shape below worked fine.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9BTx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9BTx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 424w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 848w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 1272w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9BTx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png" width="708" height="338" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:338,&quot;width&quot;:708,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:82069,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187813629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!9BTx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 424w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 848w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 1272w, https://substackcdn.com/image/fetch/$s_!9BTx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe30a8b6c-ccdc-4597-9f4f-1c5c57c1fc43_708x338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p><strong>Ejector Pin Surface Area</strong>: The ejector pin needs as large a surface area as possible; otherwise, it just indents the wax.</p></li><li><p><strong>Mold Material</strong>: PLA and PETG were easier to work with. I tried TPU, but it was prone to air bubbles from moisture in the filament, which caused leaks. I could have dried the filament properly, but that seemed like more effort than it was worth.</p></li><li><p><strong>Print Settings</strong>: Standard print settings will leak. To get a watertight mold, I increased the wall loops to 5 and used slight over-extrusion (a flow factor of 1.05 for PLA and 1.02 for PETG).</p></li></ul><p>Couple images from the process: </p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/425ab386-6455-486d-9b09-be25fb320aa5_4096x3072.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a26c00df-f024-4e1c-a562-c8e602786ff0_4096x3072.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/07918d6e-9299-4a59-88b8-d604066d74b6_4096x3072.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/65e722ff-bde1-4878-9a9d-0f9237a6a777_4096x3072.jpeg&quot;},{&quot;type&quot;:&quot;image/jpeg&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7e28dd98-9c55-43f6-8785-10074cbbcec5_4096x3072.jpeg&quot;}],&quot;caption&quot;:&quot;&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b4fa62fa-348e-4480-bb10-2a3caf2bb801_1456x1210.png&quot;}},&quot;isEditorNode&quot;:true}"></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1><strong>Other Learnings</strong></h1><ul><li><p><strong>Wick Size</strong>: I was surprised by how much this matters - there&#8217;s more to candle making than I thought. There&#8217;s a subtle balance of wicking speed, material constituents, etc. I don&#8217;t fully understand it yet, but it was fun to get a glimpse into what&#8217;s going on behind the scenes in candle design.</p></li><li><p><strong>Wax Additives</strong>: A hardening agent helps with mold release, improves shrinking, and makes the candle harder and easier to work with. I added 2% stearic acid by weight to my paraffin wax. Apparently this also improves opacity, fragrance retention, etc. Not really sure about the details on this. As I said, there&#8217;s more to candles than I thought!</p></li><li><p><strong>Draft Angle</strong>: An 8-degree draft angle worked well for ejecting the candle. 2 degrees were too hard to eject.</p></li><li><p><strong>Cooling Time is Critical</strong>: Wait for the wax to cool and shrink. Ejecting after three hours resulted in high ejection force even with 8 degree draft, launching the candle halfway across the room. After waiting overnight, it just needed a gentle tap.</p></li><li><p><strong>Mold Release</strong>: I used a paintbrush to apply oil onto the 3D printed mold as a release agent.</p></li><li><p><strong>Excess Wax</strong>: Don&#8217;t throw away wax drippings - they&#8217;re useful for repairing cosmetic defects like sink holes. I used a hot air gun to drip wax onto the problem area and fix it.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qtOV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qtOV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 424w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 848w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 1272w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qtOV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png" width="1074" height="515" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:515,&quot;width&quot;:1074,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:725215,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187813629?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qtOV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 424w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 848w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 1272w, https://substackcdn.com/image/fetch/$s_!qtOV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0ba2366-cc17-4776-98a5-011281e14f3b_1074x515.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Automated Product Validation Workflow Using AI]]></title><description><![CDATA[Testing a workflow to automate market research, competitor research, product concept images, landing pages, and ads in about 20 minutes for ~3.7USD.]]></description><link>https://luvsheth.com/p/automated-product-validation-workflow</link><guid isPermaLink="false">https://luvsheth.com/p/automated-product-validation-workflow</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Wed, 11 Feb 2026 03:10:22 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/703c9e7c-6653-4882-829f-c38fe4c74196_1200x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I have now setup a workflow to automate everything that was done in this blog post (<a href="https://luvsheth.com/p/rapid-validation-of-product-concepts">link</a>) in about 20 minutes for ~3.7USD. </p><ul><li><p>I give the tool a product idea</p><ul><li><p>It performs market research and competitor research</p></li><li><p>It provides initial research into operational requirements (licensing requirements, any other operational concerns etc)</p></li><li><p>It generates branding (brand name, colour combination, logo, taglines)</p></li><li><p>It generates product concepts and images</p></li><li><p>It generates a landing page</p></li><li><p>It generates ad copy and visuals</p></li></ul></li></ul><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!wW3Z!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!wW3Z!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 424w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 848w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 1272w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!wW3Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png" width="1456" height="75" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:75,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:64330,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!wW3Z!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 424w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 848w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 1272w, https://substackcdn.com/image/fetch/$s_!wW3Z!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e299a93-d3ce-4bc1-bbcd-91ba8aa21114_3120x160.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p></p><p>While normally using the tool, after each stage it stops and asks for input on what to change before moving on to the next step. For now to demo the tool I&#8217;ve let it run on an example fully autonomously without my input (except 2 things - I&#8217;ll talk about those later).</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Want to see what I build next? Subscribe to get notified.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p>I&#8217;ve added the output of the workflow below. I think the quality of the initial output is a 5/10 but I&#8217;m quite happy with this workflow as a first iteration and I think there&#8217;s easy ways to improve the quality massively:</p><ol><li><p>Giving it feedback between each stage already improves the output quality significantly - it was an interesting experiment to run it on full autonomous mode to see the output + it made writing this blog post easier</p></li><li><p>I can likely also improve the prompts to give it more context and &#8220;training&#8221; (eg. feeding it a couple of articles on copywriting techniques before asking it to write copy)</p></li><li><p>Using specialized tools like Leonardo.ai API for specialized portions of the work like image generation (Leonardo Blueprints are amazing)</p></li><li><p>I also need to ask it to include more detailed citations for the the research bits (eg. competitor research) so that I can cross reference important figures later</p></li></ol><p>I&#8217;m quite excited about the potential this type of workflow has on product development - being able to validate a product before building anything is going to get much much easier.</p><h1><strong>The Output</strong></h1><p>First, here is the full output: <a href="https://github.com/IcedRooibos/Mushroom-Chips-Validation-Workflow-Output-Example">https://github.com/IcedRooibos/Mushroom-Chips-Validation-Workflow-Output-Example</a>.</p><p> I will highlight some interesting bits below. </p><p>If you want to see the chat that led to the output, I&#8217;ve also attached a copy of the conversation at the end of the article - it&#8217;s quite cool to see it do its thing with minimal input.</p><h2><strong>Market Research and Competitor Research</strong></h2><ul><li><p>It&#8217;s tried to estimate market size (but only found global market size info which isn&#8217;t very useful in this context).</p></li><li><p>It also found an interesting list of competitors to use as a starting point to further understand the market </p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-bzz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-bzz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 424w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 848w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 1272w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-bzz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png" width="658" height="337" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:337,&quot;width&quot;:658,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54339,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!-bzz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 424w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 848w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 1272w, https://substackcdn.com/image/fetch/$s_!-bzz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b1874f1-b6bf-4148-b341-f4753cdcd546_658x337.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fY-N!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fY-N!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 424w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 848w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 1272w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fY-N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png" width="811" height="839" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f940b22f-fa64-4845-823d-383044cbad12_811x839.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:839,&quot;width&quot;:811,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:149537,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fY-N!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 424w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 848w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 1272w, https://substackcdn.com/image/fetch/$s_!fY-N!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff940b22f-fa64-4845-823d-383044cbad12_811x839.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2><strong>Operational Considerations</strong></h2><p>It talks about import regulations and packaging requirements as well as estimates costs across different manufacturing models. I think the estimates are off but the line items being included are a good starting point to fill in better numbers. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mAuf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mAuf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 424w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 848w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 1272w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mAuf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png" width="825" height="604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:825,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:100396,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mAuf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 424w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 848w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 1272w, https://substackcdn.com/image/fetch/$s_!mAuf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12ca7b99-6ac5-4c7a-81d5-bce471534a67_825x604.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tj6r!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tj6r!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 424w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 848w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 1272w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tj6r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png" width="688" height="1181" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1181,&quot;width&quot;:688,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:173748,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tj6r!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 424w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 848w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 1272w, https://substackcdn.com/image/fetch/$s_!Tj6r!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3dd5ef36-7e4f-4fd3-98c3-3994e6325fb9_688x1181.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2><strong>Branding</strong></h2><p>It came up with a brand name and some logo options - I think both the brand name and logo are mediocre and this is likely where human input would have been very helpful.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_k_2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_k_2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 424w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 848w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 1272w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_k_2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png" width="1456" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f275d69-a916-4948-8399-10fd0609250d_1559x685.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1173032,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_k_2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 424w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 848w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 1272w, https://substackcdn.com/image/fetch/$s_!_k_2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f275d69-a916-4948-8399-10fd0609250d_1559x685.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2><strong>Product Concepts and Images</strong></h2><p>As well as some product renders - but the branding isn&#8217;t consistent across those and the images aren&#8217;t great. This bit needs work and integration with Leonardo.ai will likely go a long way here. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!LGiK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!LGiK!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 424w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 848w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 1272w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!LGiK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png" width="1416" height="623" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:623,&quot;width&quot;:1416,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1143786,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!LGiK!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 424w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 848w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 1272w, https://substackcdn.com/image/fetch/$s_!LGiK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5b8c3f57-6279-482c-ad36-da984632fa6f_1416x623.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h2><strong>Landing Page</strong></h2><p>It came up with a landing page. Link to the site: <a href="https://umamichips-bfppijdq.manus.space/">https://umamichips-bfppijdq.manus.space/</a></p><p>Images below in case I ever take the site down later.</p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1710275e-f526-4129-84fa-b219778b185e_1606x887.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b793fd3a-6500-47d0-84d6-fe2a2290e59d_1803x675.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/408b9509-ac59-4ea3-8b3c-45b16f1c674d_2109x813.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42a11f05-ccd4-497d-80eb-726f1c9a3fce_1182x830.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d29fc4f9-508a-412f-80af-09e749401c8f_1677x620.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/450ba9fa-10fc-4008-83aa-33918dfb38c4_1655x998.png&quot;}],&quot;caption&quot;:&quot;&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3272626b-3aff-434e-9652-5b9b05ce0a02_1456x964.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p></p><h2><strong>Ad Copy</strong></h2><p>It came up with ad copy and images to go with those ads.</p><p>One variant here, but there&#8217;s a whole library of them - including platform specific ads eg. Facebook, Instagram, HKTVMall (local Hong Kong online shopping platform), Google, etc. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dm91!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dm91!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 424w, https://substackcdn.com/image/fetch/$s_!dm91!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 848w, https://substackcdn.com/image/fetch/$s_!dm91!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 1272w, https://substackcdn.com/image/fetch/$s_!dm91!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dm91!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png" width="764" height="310" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:310,&quot;width&quot;:764,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:72667,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dm91!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 424w, https://substackcdn.com/image/fetch/$s_!dm91!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 848w, https://substackcdn.com/image/fetch/$s_!dm91!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 1272w, https://substackcdn.com/image/fetch/$s_!dm91!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3523c9f8-e7c4-4cd7-86c0-88f7b586e6c3_764x310.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Tf6V!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Tf6V!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 424w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 848w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 1272w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Tf6V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png" width="1456" height="2609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/08074578-49b5-4520-b186-a50958a54f55_1536x2752.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:2609,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:5888619,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/187525932?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Tf6V!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 424w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 848w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 1272w, https://substackcdn.com/image/fetch/$s_!Tf6V!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F08074578-49b5-4520-b186-a50958a54f55_1536x2752.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><h1><strong>The Chat</strong></h1><p>I think it&#8217;s quite cool to see the whole chat play out so I&#8217;ve attached an image gallery here with the chat. </p><div class="image-gallery-embed" data-attrs="{&quot;gallery&quot;:{&quot;images&quot;:[{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b98e862a-27cf-499f-92ad-e5c2197b59e9_1063x1043.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61153fb2-b668-4e2f-8ab7-35a1d7d81820_1083x832.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7c61cc08-7ec6-4cc8-b394-6214a1e0b033_1083x922.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a2d9c332-740b-43bf-81d8-25abd0387101_1079x862.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b5416c1c-9879-4f64-a4b7-c05964e74fed_1094x817.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1eb13974-d7d0-4f85-a857-c5eaa89353a8_1071x905.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0298ae93-2e01-47d1-9db8-2476a87af7fb_1064x665.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6d5cf311-9800-4a53-8675-92a3cf4385c8_1073x737.png&quot;},{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/32224cf6-15d6-492e-bc18-d4021dd26cff_1070x920.png&quot;}],&quot;caption&quot;:&quot;&quot;,&quot;alt&quot;:&quot;&quot;,&quot;staticGalleryImage&quot;:{&quot;type&quot;:&quot;image/png&quot;,&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eac8a679-6c9e-430d-ab15-13ab70063c4c_1456x1454.png&quot;}},&quot;isEditorNode&quot;:true}"></div><p></p><h2><strong>Human Input</strong></h2><p>After sending it the initial prompt I saw it was looking into manufacturing in Hong Kong which I knew is not a good path to go down so this stopped it and told it not to consider that as an option.</p><p>In a very human-like moment of forgetfulness it forgot to make the landing page so I reminded it to do that as well. It&#8217;s OK, AI, it&#8217;s only human to forget.</p><p>For 20 minutes and ~3.7USD worth of work this is a really interesting starting point. I am sure this will only get better.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Rapid Validation of Product Concepts with AI]]></title><description><![CDATA[Using AI to materially accelerate the product validation process before starting to build]]></description><link>https://luvsheth.com/p/rapid-validation-of-product-concepts</link><guid isPermaLink="false">https://luvsheth.com/p/rapid-validation-of-product-concepts</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sun, 04 Jan 2026 15:07:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!dz75!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>What is this?</h1><p>A product validation approach I&#8217;ve been thinking about that uses AI to speed up the boring parts. The idea isn&#8217;t to remove the human from the loop&#8212;it&#8217;s to make the loop so much faster that it feels like a completely different process.</p><p>I think 10x faster/cheaper tends to have more of an impact on how you work than just &#8220;a bit faster.&#8221; When we moved from film photography to digital the workflow changed. With film you were more careful about what you shot, you had 36 shots in a roll. With digital you click as many pictures as you want and delete the ones you don&#8217;t need later. When something takes a weekend instead of a month, you&#8217;re more willing to try it. You&#8217;re more willing to throw it away if it doesn&#8217;t work. That&#8217;s the goal here. (Philosophically, I think it&#8217;s an open debate as to which approach is better but certainly the second approach wasn&#8217;t possible before so I am interested in exploring it).</p><p>I haven&#8217;t battle-tested this yet so take it with a grain of salt&#8212;but I think the approach is interesting enough to write about now and then follow up with results later after I have run through this a couple times.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">I'll share what worked (and what didn't) &#8212; subscribe to follow along</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>The Three Phases</h1><p>I&#8217;ve broken this down into three chunks: <strong>Initial Research</strong>, <strong>Validation Marketing</strong>, <strong>Iteration</strong>.</p><p>Here are the goals:</p><ul><li><p>Initial Research: This is for you to look into the idea and learn about the lay of the land and decide if you want to take this to the next step</p></li><li><p>Validation Marketing: I call this validation marketing because the goal isn&#8217;t to sell but to learn what works and collect an audience along the way (e-mail lists, followers, etc.)</p></li><li><p>Iteration: This is the human in the loop - take the learnings from the previous two stages and decide what to do next. Tweak the product concept? Change the ads? Start over with another product concept entirely? If done right, you now have an audience from step two to talk to about your tweaks before you start the loop again.</p></li></ul><h1>A Quick Note About Tools</h1><p>Here are the tools I find useful and have used for items in the rest of the post below.</p><p>(Note: I gain nothing from you signing up to them, this is just to share my current workflow).</p><ul><li><p>Kagi - privacy friendly search engine</p><ul><li><p>Their search-assisted AI is the best I have found so far. I use the Ultimate Plan as it has a special research mode.</p></li></ul></li><li><p>OpenWebUI - self hosted chatGPT UI</p><ul><li><p>This is the &#8220;heart&#8221; of the system and how the output from a lot of these sections talk to each other. I add output from all AI models to an openWebUI folder (called a &#8220;knowledge base&#8221;) that the model can reference later</p></li></ul></li><li><p>Canva</p><ul><li><p>Logo generation</p></li></ul></li><li><p>Leonardo.ai</p><ul><li><p>Image and video AI models - I really like the outputs from this tool</p></li></ul></li><li><p>Huemint - colour palette generator</p><ul><li><p>This comes up with colours palettes very quickly and I can cycle through a few before I hit something I think is a good fit for a specific idea</p></li></ul></li><li><p>Carrd / GetResponse:</p><ul><li><p>For landing pages.</p></li><li><p>I have used Carrd for a long time and it&#8217;s a good tool</p></li><li><p>GetResponse claims to be more integrated from an analytics and email marketing perspective. It even offers basic ad management. Seems interesting enough that I am taking it for a spin.</p></li></ul></li></ul><h1>Initial Research</h1><p>The goal here is to quickly figure out:</p><ol><li><p><strong>Are people talking about this problem?</strong> &#8212; Find mentions of the problem or similar problems online. Forums, Reddit, Twitter, product reviews complaining about something. You want to know if real people actually care.</p></li><li><p><strong>What competitor products exist?</strong> &#8212; Who&#8217;s already selling something in this space? What do their products look like? What do customers say about them?</p></li><li><p><strong>What competing solutions exist for the same problem?</strong> &#8212; Sometimes the competition isn&#8217;t a direct competitor&#8212;it&#8217;s a workaround, a DIY solution, or just people tolerating the problem.</p></li></ol><p>This is also a good place to add constraints that are important to you (for example &#8220;Could this go from idea to revenue in 90 days?&#8221;). </p><h2>How?</h2><ul><li><p>Kagi&#8217;s research assistant is great for the research phase to try and find information and put together a summary to the questions you feel are important to have answered</p></li><li><p>Once I have done AI-assisted research I will move the collected information to OpenWebUI so that future conversations can reference this research</p></li></ul><p>The output of this phase: enough context to decide whether to keep going, and enough material to inform your product positioning.</p><h1>Marketing</h1><p>Once you&#8217;ve decided the idea is worth testing, you need to get something in front of people. The goal is minimum viable marketing&#8212;just enough to run a credible test.</p><h2>Minimum Viable Branding</h2><p>You don&#8217;t need a brand agency. You need:</p><ul><li><p>A brand name (openWebUI brainstorm with AI with previous conversation context, pick one)</p></li><li><p>A tagline (same)</p></li><li><p>A color palette (I use <a href="https://huemint.com/gradient-3/">Huemint</a>)</p></li><li><p>A logo (Canva&#8217;s AI logo generator works fine)</p></li></ul><p>This takes maybe 15 minutes. It won&#8217;t win design awards but it&#8217;s good enough to pass the sniff test and get the audience to look at the product and decide if they want to demonstrate interest (eg. by signing up to your e-mail list).</p><h2>Audience Definition</h2><p>Who exactly are you selling to? I work through this with AI as well:</p><ul><li><p>What&#8217;s the problem? What are current alternatives? Why are they inadequate?</p></li><li><p>Come up with 3-5 candidate customer profiles</p></li><li><p>Pick one primary target (you should do this one, not AI)</p></li><li><p>Write a one-sentence customer definition</p></li><li><p>Sanity check: are they reachable? Is the market large enough? Use your advertising platform of choice&#8217;s targeting tools to check.</p></li></ul><p>In reality I do this before branding because this should feed into the branding but to read a blog post it flows better this way so I have left branding first.</p><h2>Asset Generation</h2><p>This is where AI image/video generation is genuinely useful. You can create product visuals without having a product.</p><ul><li><p>Pull reference images from competitors or suppliers</p></li><li><p>Use AI tools to generate product shots, carousel images, lifestyle images, with the branding you want</p></li><li><p>Generate short videos from images if needed</p></li></ul><p>I&#8217;ve been using Leonardo.ai and the quality is good enough for ads and landing pages. </p><p>It&#8217;s quite believable that AI could do marketing research and come up with some audience definition information or landing page copy. It&#8217;s possibly a bit harder to believe that it could do it well. </p><p>But asset generation seems like the kind of thing AI can&#8217;t get right. It was the missing piece for a while, in my opinion. But the models are good enough now to get what we need out of them.</p><p>As an example, if this is the input to the system:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dz75!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dz75!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 424w, https://substackcdn.com/image/fetch/$s_!dz75!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 848w, https://substackcdn.com/image/fetch/$s_!dz75!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 1272w, https://substackcdn.com/image/fetch/$s_!dz75!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dz75!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png" width="992" height="655" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:655,&quot;width&quot;:992,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1117137,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/183444992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dz75!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 424w, https://substackcdn.com/image/fetch/$s_!dz75!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 848w, https://substackcdn.com/image/fetch/$s_!dz75!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 1272w, https://substackcdn.com/image/fetch/$s_!dz75!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffc8b4f97-31fe-440c-aab5-d6655c872dfd_992x655.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><br>Here&#8217;s what we can get out of it.</p><p>Video for advertisement:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;7d75d1d7-c4bc-474b-b678-9a0476813a04&quot;,&quot;duration&quot;:null}"></div><p>Image carousel for landing page:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Bjr8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Bjr8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 424w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 848w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Bjr8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png" width="896" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:896,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1739039,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/183444992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Bjr8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 424w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 848w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 1272w, https://substackcdn.com/image/fetch/$s_!Bjr8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdd3092d8-9218-4a5b-8dcc-42ab5c835193_896x1200.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Copy Generation</h2><ul><li><p>Landing page copy: I feed the knowledge base context to openWebUI brainstorm with Opus to write landing page copy</p><ul><li><p>I have a skeleton structure for the landing page that I feed to the AI as well so it knows what kind of things to generate. In theory we are leaving some creativity on the table in terms of structure but a well formatted landing page is a good starting point and my hope is the speed we get out of this will make it worth it.</p></li><li><p>Here&#8217;s an image of the prompt I use (+ it has all the knowledge of conversations prior to this):</p></li></ul></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9ois!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9ois!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 424w, https://substackcdn.com/image/fetch/$s_!9ois!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 848w, https://substackcdn.com/image/fetch/$s_!9ois!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 1272w, https://substackcdn.com/image/fetch/$s_!9ois!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9ois!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png" width="673" height="1051" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1051,&quot;width&quot;:673,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73284,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://luvsheth.com/i/183444992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9ois!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 424w, https://substackcdn.com/image/fetch/$s_!9ois!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 848w, https://substackcdn.com/image/fetch/$s_!9ois!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 1272w, https://substackcdn.com/image/fetch/$s_!9ois!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0b794e37-e466-4856-ba63-a18ef4fea8cb_673x1051.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Ad copy: Same process, but formatted for ads</p></li><li><p>Ad scripts: If you&#8217;re doing video ads, get AI to draft scripts based on your audience and positioning then generate then using your tool of choice</p></li></ul><h2>Landing Page</h2><p>I have made a template in two website builders based on the structure I shared above and can plug in the copy and assets. Nothing fancy. The point is to have somewhere to send traffic to.</p><p>In terms of tools I am currently testing both Carrd and GetResponse. I have used Carrd for a long time and it&#8217;s solid, but GetResponse claims better integration with analytics and email so I am taking it for a spin. I&#8217;m quite happy to fall back to Carrd if GetResponse causes issues. This is an implementation detail anyway and not really core to the experiment.</p><h1>Iteration: Human in the Loop</h1><p>At this point you&#8217;re ready to run ads and start learning. The human is still very much in the loop. You&#8217;re making decisions about what to test, how to interpret results, whether to iterate or kill the idea.</p><p>The difference is the loop is now a lot faster and cheaper to execute. You can test an idea in a day instead of a couple weeks. You can test multiple ideas in parallel. And when something doesn&#8217;t work, you haven&#8217;t sunk much into it. This also sounds like the type of process that is easy to operationalize and scale; run by a small team testing multiple ideas in parallel. Something to explore later.</p><h1>What&#8217;s Next?</h1><p>I&#8217;m going to run a few ideas through this process and see what happens. Will report back on what worked and what didn&#8217;t. I think there are some parts of this process that raise a few questions (how do I know if it&#8217;s a product issue or a ad targetting issue, for example?) but I am hoping as I run this playbook a bit more I can learn about what happens in the real world.</p><p>If you have thoughts or have tried something similar, I&#8217;d be curious to hear about it.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Portable Battery Powered Lights That React to Music]]></title><description><![CDATA[I think it's cool that portable speakers have become so common that you can organize an event in fairly remote locations and have decent music. I think it would be cool if the same were true of lights.]]></description><link>https://luvsheth.com/p/portable-battery-powered-lights-that</link><guid isPermaLink="false">https://luvsheth.com/p/portable-battery-powered-lights-that</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sun, 02 Feb 2025 10:07:02 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2f1f07b2-ec35-44c2-ad73-2cd3c55c070a_1456x1048.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>What is it?</h1><p>Battery powered portable lights that can sync with one another and sync to the music. I think it's cool that portable speakers have become so common that you can organize an event in fairly remote locations and have decent music. I think it would be cool if the same were true of lights.</p><p>This video below shows what the setup looks like for now - the hardware works fine but now I need to spend some time experimenting with different effects to see which ones look good together. A couple interesting effect combinations from my testing are shown below.</p><p>I also found this setup looks best in the dark but I haven't been able to figure out how to use my phone to record it without overexposing parts of the video - apologies!</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;7dfc0829-dced-4a46-ba37-d48e9a3fc3a2&quot;,&quot;duration&quot;:null}"></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">P.S: Feel free to subscribe to hear about any other projects I end up working on.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Why did I make it?</h1><p>The main aim was to have something simple and easy to carry to an NYE event. Initial plan was to just make one but after I made one I realized it would be way more interesting if there were a bunch of them synced up (4? 10? 1 million? Not sure). </p><p>I am quite into music and thought this would also be interesting to set up during performances just to add a bit of visual interest. </p><h1>Process</h1><p>For this project I wanted results quickly so I made sure to view it as an integration project rather than a development project. This made it feel like I sidestepped everything technical and so I almost don't want to write about it. Except I think making things work while avoiding the difficult bits is also an important engineering skill  - so here we are.</p><p>There were still some hiccups along the way. One fun issue I had was a shipment got lost on the way so to get one unit ready in time for an event I had to use a Pi Pico solely as a voltage regulator to power an ESP32 because the Pico dev board had a wider input voltage range (unfortunately doing that type of thing is my idea of fun). In any case - the hiccups are irrelevant to the outcome so let&#8217;s focus on the final design.</p><p>Here are the different components that were used to make each light:</p><p>The Xiao ESP32 S3 (https://wiki.seeedstudio.com/xiao_esp32s3_getting_started/) is the selected dev board. The Xiao is a tiny little development board that is designed to be able to run off battery voltage levels which is very convenient.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cbUQ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cbUQ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cbUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/70b16033-063c-450d-9216-af5ae0884867_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2903684,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cbUQ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!cbUQ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F70b16033-063c-450d-9216-af5ae0884867_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I used an 18650 cell because they're easy to source and can be easily charged in an external charger so I don't have to bother adding fast charge into the device (though there is a backup slow charger that comes "free" with the Xiao - good to have for after the event where you can just plug in a USB C cable and let it charge overnight)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!D_jU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!D_jU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!D_jU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2764934,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!D_jU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!D_jU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F73069778-7553-4ac9-a04a-8eec96d170cf_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The 18650 holder has a protection circuit built in.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!CBQq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!CBQq!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!CBQq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3427801,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!CBQq!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!CBQq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7bc0a0ad-56f4-4bea-81d0-5efc3efdd674_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There's a switch that connects and disconnects battery power from the circuit for to quickly toggle power to the board.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3GR7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3GR7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3GR7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2502422,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!3GR7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!3GR7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F16ab585c-fdff-4cfe-984f-e0d0145bc42b_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I found WS2812 LED boards that had LEDs arranged into concentric circles and came with wires to connect them up together. Very convenient but the wires are longer than I'd like. They are rated for 5V but work just fine off battery power (saves the cost / space / current draw of having a boost converter on board)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oVPy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oVPy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oVPy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:4307038,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oVPy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!oVPy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F02286c2c-48ba-4277-8e52-60cca8e51faf_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And there's an INMP441 mic that operates off the 3V3 of the Xiao board and communicates with the ESP32 over I2S.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QAWv!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QAWv!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QAWv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2518776,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QAWv!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!QAWv!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8d9cdba7-8884-4038-aadc-217ac28bf6d4_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>WLED - Open source software which has been amazing to get this up and running quickly. It allowed me to quickly experiment with different light effects and start working out what looks good together. Huge thanks to the WLED contributors. Link if you'd like to learn more: https://kno.wled.ge/</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FB6e!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FB6e!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FB6e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:161024,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FB6e!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!FB6e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd25116eb-de4c-4d8d-b957-b6aa27150a81_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Chassis / diffuser - I created some rough designs for the housing and 3D printed them. There's a hook to be able to hang the lights as well as prevent it from rolling off if it's placed somewhere. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s1n8!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s1n8!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s1n8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png" width="1456" height="804" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:804,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3401268,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!s1n8!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 424w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 848w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 1272w, https://substackcdn.com/image/fetch/$s_!s1n8!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb314fb0c-c2a4-4888-9fd2-2d99b9011d19_2305x1273.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><br>There's also a detachable light diffuser.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;5c616625-b1f8-40de-b665-4e72a8ae70bb&quot;,&quot;duration&quot;:null}"></div><p>No diffusion looks cool if the brightness is turned down / if it's still daytime / or it's facing away from the viewers since the environment then does a decent job of diffusing the light. Here's the same effect with and without a diffuser.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;7a80b533-0690-492d-9dec-4b25cb63dce4&quot;,&quot;duration&quot;:null}"></div><p>The slicer settings used to 3D print the diffuser were quite important - different infill settings make the lights feel slightly different and for now I have settled on the infill method shown on the right in the video below. I think there's still room for improvement here.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;41f97fa0-e6b1-49b6-8610-0a21118c8c49&quot;,&quot;duration&quot;:null}"></div><p>Here's a rough connection diagram:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dFgf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dFgf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 424w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 848w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 1272w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dFgf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png" width="1456" height="533" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:533,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:67716,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!dFgf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 424w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 848w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 1272w, https://substackcdn.com/image/fetch/$s_!dFgf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F490acb3f-c714-4a21-887e-403b4abf3dbb_1600x586.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Another Variant</h1><p>My mom liked these and wanted to take a couple to a monastery she volunteers at. I made a non-battery powered version to give to them since I was a bit concerned about these being used in the rain or thrown around and didn't want anyone to take on the associated safety risks. These are powered by USB-C and if they want it to be portable they can of course just plug it into a power bank so it's still good enough for their use case. Since I didn't need the battery capabilities of the Xiao here I went with the Waveshare ESP32 S3 which worked fine as well.</p><h1>What's next?</h1><ul><li><p>Custom PCB?</p><ul><li><p>I am wondering whether I want to spend the time putting this down onto a PCB so I can make way more of these. Tempting. Right now the assembly is manual and being able to put everything onto a PCB will make things a lot simpler to assemble. I should probably do the lights and the WLED control board as two separate boards that way I can have different light attachments that can be swapped out for different events.</p></li><li><p>Not sure it's worth the time as I don't know if I want more of these so I will first start using the few that I have built so far and then decide whether I want more.</p></li></ul></li><li><p>Human Input</p><ul><li><p>I think it would be very cool for me to be able to &#8220;play&#8221; the lights as an instrument by playing a 8x8 MIDI controller like the one below (for anyone unfamiliar with what&#8217;s shown below - it&#8217;s traditionally used to play music and is similar to an electric piano but in a different form factor)</p></li></ul></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!qJfe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!qJfe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!qJfe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg" width="1200" height="1200" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1200,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:136589,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!qJfe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 424w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 848w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!qJfe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6c6488ce-f27a-4990-b5e2-55a2ab9f913c_1200x1200.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">P.S: Feel free to subscribe to hear about any other projects I end up working on.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Running a PyTorch machine learning model on an ESP32]]></title><description><![CDATA[I wanted to figure out how to run a PyTorch machine learning model on an ESP32.]]></description><link>https://luvsheth.com/p/running-a-pytorch-machine-learning</link><guid isPermaLink="false">https://luvsheth.com/p/running-a-pytorch-machine-learning</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Fri, 10 Nov 2023 13:41:14 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/8c1d5d36-5137-447d-9ecb-a8728a552473_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I wanted to figure out how to run a PyTorch machine learning model on an ESP32. I use MicroPython pretty often so would be even better if I could do it natively on MicroPython.</p><p>I didn't really care what the model did so I chose handwriting detection as an arbitrary test case. There is a PCB with a bunch of pads that I use as touch sensors and then use my finger to draw alphabets on them and try and get the model to guess which letter I drew. </p><div id="vimeo-883265602" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;883265602&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/883265602?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p>Couple things I find cool about this:</p><ul><li><p>Model was trained on PyTorch on my laptop and inference performed on an ESP32</p></li><li><p>The way this is implemented it would be quite easy to completely change the model architecture and reconfigure it to do other things like audio recognition or object detection</p></li><li><p>The ML related custom code-base is extremely small (~120 lines of MicroPython code and ~235 lines of C optimizations)</p></li><li><p>Good enough for real-time inference (needs 31ms for inference)</p></li><li><p>Has 95% validation set accuracy (as a reference point - a simpler technique like measuring distance from the mean of each category got only 31% accuracy)</p></li></ul><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Hardware</h1><ul><li><p>ESP32 connected to a display</p></li><li><p>Pads on a PCB that act as touch sensors</p><ul><li><p>Only 13 of the 16 pads are connected due to MCU peripheral limitations - the MCU only has 13 capacitive touch input input pins</p></li></ul></li><li><p>USB for power</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QYN_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QYN_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 424w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 848w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 1272w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QYN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png" width="1456" height="551" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:551,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:791885,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!QYN_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 424w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 848w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 1272w, https://substackcdn.com/image/fetch/$s_!QYN_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46792998-1706-4b33-9c52-0420bbd00bf7_1890x715.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Data</h1><ul><li><p>To collect training data I used my finger to draw out specific shapes for each letter and stored that data onto the ESP</p></li><li><p>Each "gesture" has touch sensing data from each of the pads collected at 50ms intervals for 1.5s</p></li><li><p>The data array is 13 sensors x 30 datapoints, each datapoint being 50ms apart.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!txPI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!txPI!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 424w, https://substackcdn.com/image/fetch/$s_!txPI!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 848w, https://substackcdn.com/image/fetch/$s_!txPI!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 1272w, https://substackcdn.com/image/fetch/$s_!txPI!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!txPI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png" width="1456" height="441" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:441,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90567,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!txPI!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 424w, https://substackcdn.com/image/fetch/$s_!txPI!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 848w, https://substackcdn.com/image/fetch/$s_!txPI!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 1272w, https://substackcdn.com/image/fetch/$s_!txPI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3456ec63-fa3c-46c1-ad41-b62a4221ce48_1987x602.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Since this is a 2D array of floats, the techniques that apply to image classification models will also apply here.</p></li><li><p>To see why, let's visualize the data. Below is what one sample of each 1.5s "recording" of the input data looks like when visualized for each letter. The more green something is, the higher the capacitance i.e. the stronger the touch detection signal (larger contact area will lead to larger signal amplitude)</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8cUE!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8cUE!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 424w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 848w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 1272w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8cUE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png" width="1366" height="924" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:924,&quot;width&quot;:1366,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:25698,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8cUE!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 424w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 848w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 1272w, https://substackcdn.com/image/fetch/$s_!8cUE!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1de4aa16-75f9-4808-bb28-d0a4c5dabf16_1366x924.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Data is stored onto the ESP32 as a CSV file then transferred onto desktop for training</p></li><li><p>I collected 120 samples of each letter which takes about 3 minutes of writing the same letter onto the pad each time (Note: Since I had to manually record the data I have only implemented detection for the alphabets A, B, C, X, Y, and Z. Doing all 26 alphabets would be around 1.5 hours of just writing alphabets onto the touchpad - not necessary for a proof of concept on a for-fun blog post)</p></li></ul><h1>Training - PyTorch / Laptop</h1><ul><li><p>Here is the model architecture I landed on after trying a couple.</p></li></ul><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126119997\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>model</span> <span class=pl-c1>=</span> <span class=pl-s1>nn</span>.<span class=pl-v>Sequential</span>(</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### 13 x 30 input</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### 2 stride, 3x3 kernel, 3 output channel convolution layer </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### = 3 channels x 6 rows x 14 columns output</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Conv2d</span>(<span class=pl-c1>1</span>, <span class=pl-c1>3</span>, (<span class=pl-c1>3</span>,<span class=pl-c1>3</span>), <span class=pl-c1>2</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Activation layer</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>ReLU</span>(), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Dropout to help generalize</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Dropout</span>(<span class=pl-c1>0.1</span>), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### 2 stride, 3x3 kernel, 12 output channel convolution layer </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### = 12 channels x 2 rows x 6 columns output</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Conv2d</span>(<span class=pl-c1>3</span>, <span class=pl-c1>12</span>, (<span class=pl-c1>3</span>,<span class=pl-c1>3</span>), <span class=pl-c1>2</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-model-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Activation layer</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-model-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>ReLU</span>(), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-model-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-model-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Dropout to help generalize</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-model-py-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Dropout</span>(<span class=pl-c1>0.1</span>), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-model-py-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-model-py-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### 1 stride, 2x3 kernel, 12 output channel convolution layer </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-model-py-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### = 12 channels x 1 row x 4 columns output</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-model-py-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Conv2d</span>(<span class=pl-c1>12</span>, <span class=pl-c1>12</span>, (<span class=pl-c1>2</span>,<span class=pl-c1>3</span>), <span class=pl-c1>1</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-model-py-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-model-py-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Activation layer</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-model-py-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>ReLU</span>(), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-model-py-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-model-py-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Dropout to help generalize</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-model-py-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Dropout</span>(<span class=pl-c1>0.1</span>), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-model-py-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-model-py-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Reshape data from 12 x 1 x 4 tensor -&amp;gt; 48 long vector</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-model-py-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Flatten</span>(), </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-model-py-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-model-py-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Linear layer with 48 inputs and 7 outputs </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L38\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-model-py-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### One output each for: </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L39\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-model-py-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### no gesture detected / A / B / C / X / Y / Z)</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L40\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-model-py-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-s1>nn</span>.<span class=pl-v>Linear</span>(<span class=pl-c1>48</span>,<span class=pl-c1>7</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L41\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-model-py-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t) </td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/a512537d05b01742934d768040f13311/raw/bc1103e3b7c870e895345a588bcc10dd3742d72b/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/a512537d05b01742934d768040f13311#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126119997" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">model</span> <span class="pl-c1">=</span> <span class="pl-s1">nn</span>.<span class="pl-v">Sequential</span>(</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### 13 x 30 input</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### 2 stride, 3x3 kernel, 3 output channel convolution layer </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### = 3 channels x 6 rows x 14 columns output</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Conv2d</span>(<span class="pl-c1">1</span>, <span class="pl-c1">3</span>, (<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-c1">2</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Activation layer</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">ReLU</span>(), </td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Dropout to help generalize</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Dropout</span>(<span class="pl-c1">0.1</span>), </td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### 2 stride, 3x3 kernel, 12 output channel convolution layer </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### = 12 channels x 2 rows x 6 columns output</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model-py-LC16" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Conv2d</span>(<span class="pl-c1">3</span>, <span class="pl-c1">12</span>, (<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-c1">2</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model-py-LC17" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-model-py-LC18" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Activation layer</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-model-py-LC19" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">ReLU</span>(), </td>
        </tr>
        <tr>
          <td id="file-model-py-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-model-py-LC20" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-model-py-LC21" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Dropout to help generalize</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-model-py-LC22" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Dropout</span>(<span class="pl-c1">0.1</span>), </td>
        </tr>
        <tr>
          <td id="file-model-py-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-model-py-LC23" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-model-py-LC24" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### 1 stride, 2x3 kernel, 12 output channel convolution layer </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-model-py-LC25" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### = 12 channels x 1 row x 4 columns output</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-model-py-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Conv2d</span>(<span class="pl-c1">12</span>, <span class="pl-c1">12</span>, (<span class="pl-c1">2</span>,<span class="pl-c1">3</span>), <span class="pl-c1">1</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-model-py-LC27" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-model-py-LC28" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Activation layer</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-model-py-LC29" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">ReLU</span>(), </td>
        </tr>
        <tr>
          <td id="file-model-py-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-model-py-LC30" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-model-py-LC31" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Dropout to help generalize</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-model-py-LC32" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Dropout</span>(<span class="pl-c1">0.1</span>), </td>
        </tr>
        <tr>
          <td id="file-model-py-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-model-py-LC33" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-model-py-LC34" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Reshape data from 12 x 1 x 4 tensor -&gt; 48 long vector</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-model-py-LC35" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Flatten</span>(), </td>
        </tr>
        <tr>
          <td id="file-model-py-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-model-py-LC36" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-model-py-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-model-py-LC37" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Linear layer with 48 inputs and 7 outputs </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L38" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-model-py-LC38" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### One output each for: </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L39" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-model-py-LC39" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### no gesture detected / A / B / C / X / Y / Z)</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L40" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-model-py-LC40" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-s1">nn</span>.<span class="pl-v">Linear</span>(<span class="pl-c1">48</span>,<span class="pl-c1">7</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L41" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-model-py-LC41" class="blob-code blob-code-inner js-file-line">&#9;) </td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/a512537d05b01742934d768040f13311/raw/bc1103e3b7c870e895345a588bcc10dd3742d72b/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/a512537d05b01742934d768040f13311#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p></p><ul><li><p>This model has 1585 parameters in total and requires 11,287 floating point operations.</p></li><li><p>I wouldn't be surprised if this architecture can be optimized further to have fewer parameters (reduce storage requirements) and reduce the number of floating point operations (run faster by reducing the amount of computation required)</p></li><li><p>It got 95% validation set accuracy but in real life testing there's still plenty of room for improvement because it occasionally confuses one letter for another or is not confident enough about the letter it predicts</p></li><li><p>I should collect more training data with more varied ways of writing the letters and that will probably improve the model. eg. B needs to be written a specific way because that's how I ended up writing it while I was recording training data.</p></li><li><p>This model took 13 minutes to train on my laptop with an RTX4060 to get to 95% accuracy (I could get to around 90% accuracy by training for 2.5 minutes)</p></li></ul><p>I won't get too into the details of how the model was trained - that's not really the focus of this article. The key thing to note is there is a model that takes 13 x 30 matrix of touch sensor data as input and can predict which of the 6 alphabets it is with 95% accuracy (in theory - in practice it is worse).</p><p>The default way to store the weights for a PyTorch models is a .pt file but since we want to write our own weights loader in micropython it will be a lot easier to save the weights as a JSON file. Luckily this is pretty easy and can be done with:</p><pre><code>with open(f'{fname}.json', 'w') as json_file:
   json.dump(model.state_dict(), json_file,cls=EncodeTensor)</code></pre><p>We will look at how to load these into our MicroPython model later but first - we need to actually make the MicroPython model.</p><h1>Inference - MicroPython / ESP32</h1><ul><li><p>To recreate the model for inference on the ESP32 here's what we need to do:</p><ol><li><p>Recreate the different model layers (<code>nn.Conv2d</code>, <code>nn.Linear</code>, <code>nn.ReLU</code>, <code>nn.Flatten</code>)</p></li><li><p>Write a weights loader that can read the JSON weights file and load the weights into the model layers from step 1</p></li><li><p>Performance optimizations to speedup inference (optional, of course)</p></li><li><p>Validate results against running the model with same data on desktop to ensure same output</p></li></ol></li></ul><h2>Creating different blocks</h2><ul><li><p> I really just needed 5 types of layers - <code>nn.Conv2d</code>, <code>nn.Linear</code>, <code>nn.ReLU</code>, <code>nn.Flatten</code>, and a dummy layer that does nothing to simulate the <code>nn.Dropout</code> layers that don't do anything during inference and only make a difference during training.</p></li></ul><p>I first wrote all the code in pure MicroPython so that I could validate my logic and find out which bits of code were slow and needed to be sped up using C.</p><p>I'm going to show how the most complicated layer (the convolution layer) works below since I want to show that even that isn't really a lot of code and is actually quite easy to implement. At the end of the article I'll include all the layers as an appendix so anyone that wants to can have a look.</p><p>For those who don't care to read the code (I get it!) here's a quick walkthrough showing you what's being done. Note that I'm going to assume you already know what a convolution is - if not, check this out (<a href="https://www.youtube.com/watch?v=O6_-FWnacj0">link</a>). Alternatively for the purposes of this article you can think of it like this: a convolution takes in a 2D array as an input and applies a function to it and gives back another 2D array as an output. The function can be something like edge detection and the output can be a 2D array where all edges are white and any pixel that isn't an edge is black.</p><p>Back to the layer implementation - an actual convolution layer can have multiple input channels but I've shown a simplified case with one input channel and multiple output channels below to keep things easy to understand. With one input channel what a convolution layer does is apply <code>n_out_channel</code> number of kernels (functions) to the input "image". As an example - if I had a convolution layer that had 3 output channels and the channels detected left edges, top edges, and outlines then this is what that would look like. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0HRJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0HRJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0HRJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:317300,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0HRJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!0HRJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F84fdf125-1f57-442d-bb19-ff6240de7590_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Note: Having multiple input channels isn't much more complicated - you apply each kernel to each input channel and them sum up the results for each output channel at the end.</figcaption></figure></div><p>The first layer of our model also has one input and 3 outputs but the kernels seem more complicated than just edge detection. Here is what the first convolution layer of the model I trained actually does. I could take a guess as to what it might be doing but honestly I'm not confident so let's leave that out for now. There are techniques to figure what the different layers are doing but that's probably a whole blog post in and of itself.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!5hcy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!5hcy!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!5hcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png" width="1280" height="720" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:720,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32395,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!5hcy!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 424w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 848w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 1272w, https://substackcdn.com/image/fetch/$s_!5hcy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F337c77a0-436b-456b-97ae-69b05dca2b18_1280x720.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In code, the nn.Conv2d equivalent is:</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120117\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>convLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>in_channels</span>, <span class=pl-s1>out_channels</span>, <span class=pl-s1>kernel_size</span>: <span class=pl-s1>tuple</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span> <span class=pl-c1>=</span> [[<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>in_channels</span>)] <span class=pl-k>for</span> <span class=pl-s1>_2</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                        <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> [<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>stride</span> <span class=pl-c1>=</span> <span class=pl-s1>stride</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernel_size</span> <span class=pl-c1>=</span> <span class=pl-s1>kernel_size</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>conv_func</span> <span class=pl-c1>=</span> <span class=pl-s1>convolution2D</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>output_data</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>out_channel</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>channel_output</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>for</span> <span class=pl-s1>in_channel</span>, <span class=pl-s1>image</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>channel_output</span>.<span class=pl-en>append</span>(<span class=pl-en>conv_func</span>(<span class=pl-s1>image</span>, <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>[<span class=pl-s1>out_channel</span>][<span class=pl-s1>in_channel</span>],<span class=pl-s1>self</span>.<span class=pl-s1>stride</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### Matrix addition operation</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### sum up all the different outputs for each channel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>summed_channel_output</span> <span class=pl-c1>=</span> <span class=pl-en>sumMatrices</span>(<span class=pl-s1>channel_output</span>) </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-model-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>### Add the bias for each channel to each element </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-model-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>### in the output matrix for that channel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-model-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>biased_channel_output</span> <span class=pl-c1>=</span> <span class=pl-en>addBias</span>(<span class=pl-s1>summed_channel_output</span>, <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>out_channel</span>]) </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-model-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>output_data</span>.<span class=pl-en>append</span>(<span class=pl-s1>biased_channel_output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-model-py-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>output_data</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-model-py-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-model-py-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>convolution2D</span>(<span class=pl-s1>image</span>, <span class=pl-s1>kernel</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-model-py-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Convolve single 2D matrix with kernel using stride</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-model-py-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### returns a single 2D matrix</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-model-py-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-model-py-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Get dimensions of the input matrix (image) and the kernel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-model-py-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>image_height</span>, <span class=pl-s1>image_width</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>image</span>)), <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>image</span>[<span class=pl-c1>0</span>]))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-model-py-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>kernel_height</span>, <span class=pl-s1>kernel_width</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>kernel</span>)), <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>kernel</span>[<span class=pl-c1>0</span>]))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-model-py-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-model-py-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Calculate dimensions of the output image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-model-py-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output_height</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_height</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_height</span>) <span class=pl-c1>//</span> <span class=pl-s1>stride</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-model-py-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output_width</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_width</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_width</span>) <span class=pl-c1>//</span> <span class=pl-s1>stride</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-model-py-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-model-py-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Initialize output image with zeros</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-model-py-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output</span> <span class=pl-c1>=</span> [[<span class=pl-c1>0</span>]<span class=pl-c1>*</span><span class=pl-s1>output_width</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>output_height</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L38\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-model-py-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L39\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-model-py-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Iterate over the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L40\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-model-py-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-c1>0</span>, <span class=pl-s1>image_height</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L41\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-model-py-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c>### optimization</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L42\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-model-py-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>output_y</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span><span class=pl-c1>//</span><span class=pl-s1>stride</span> </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L43\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-model-py-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>j</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-c1>0</span>, <span class=pl-s1>image_width</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L44\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-model-py-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t        <span class=pl-c>### optimization</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L45\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-model-py-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>output_x</span> <span class=pl-c1>=</span> <span class=pl-s1>j</span><span class=pl-c1>//</span><span class=pl-s1>stride</span> </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L46\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-model-py-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### Check if the kernel can fit in the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L47\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-model-py-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>if</span> <span class=pl-s1>i</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_height</span> <span class=pl-c1>&amp;lt;=</span> <span class=pl-s1>image_height</span> <span class=pl-c1>and</span> <span class=pl-s1>j</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_width</span> <span class=pl-c1>&amp;lt;=</span> <span class=pl-s1>image_width</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L48\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-model-py-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-c>### Apply the kernel to the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L49\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-model-py-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-k>for</span> <span class=pl-s1>m</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>kernel_height</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L50\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-model-py-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-s1>i_plus_m</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span><span class=pl-c1>+</span><span class=pl-s1>m</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L51\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-model-py-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-k>for</span> <span class=pl-s1>n</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>kernel_width</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L52\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-model-py-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                        <span class=pl-s1>output</span>[<span class=pl-s1>output_y</span>][<span class=pl-s1>output_x</span>] <span class=pl-c1>+=</span> <span class=pl-s1>image</span>[<span class=pl-s1>i_plus_m</span>][<span class=pl-s1>j</span><span class=pl-c1>+</span><span class=pl-s1>n</span>] <span class=pl-c1>*</span> <span class=pl-s1>kernel</span>[<span class=pl-s1>m</span>][<span class=pl-s1>n</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L53\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-model-py-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>output</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc/raw/449f39d8c83143cecd64ebc51277a6fe530165af/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120117" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">convLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">in_channels</span>, <span class="pl-s1">out_channels</span>, <span class="pl-s1">kernel_size</span>: <span class="pl-s1">tuple</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span> <span class="pl-c1">=</span> [[<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">in_channels</span>)] <span class="pl-k">for</span> <span class="pl-s1">_2</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">                        <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> [<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">stride</span> <span class="pl-c1">=</span> <span class="pl-s1">stride</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernel_size</span> <span class="pl-c1">=</span> <span class="pl-s1">kernel_size</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">conv_func</span> <span class="pl-c1">=</span> <span class="pl-s1">convolution2D</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">output_data</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">out_channel</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">channel_output</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">for</span> <span class="pl-s1">in_channel</span>, <span class="pl-s1">image</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">channel_output</span>.<span class="pl-en">append</span>(<span class="pl-en">conv_func</span>(<span class="pl-s1">image</span>, <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>[<span class="pl-s1">out_channel</span>][<span class="pl-s1">in_channel</span>],<span class="pl-s1">self</span>.<span class="pl-s1">stride</span>))</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### Matrix addition operation</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model-py-LC16" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### sum up all the different outputs for each channel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model-py-LC17" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">summed_channel_output</span> <span class="pl-c1">=</span> <span class="pl-en">sumMatrices</span>(<span class="pl-s1">channel_output</span>) </td>
        </tr>
        <tr>
          <td id="file-model-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-model-py-LC18" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">### Add the bias for each channel to each element </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-model-py-LC19" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">### in the output matrix for that channel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-model-py-LC20" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">biased_channel_output</span> <span class="pl-c1">=</span> <span class="pl-en">addBias</span>(<span class="pl-s1">summed_channel_output</span>, <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">out_channel</span>]) </td>
        </tr>
        <tr>
          <td id="file-model-py-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-model-py-LC21" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">output_data</span>.<span class="pl-en">append</span>(<span class="pl-s1">biased_channel_output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-model-py-LC22" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">output_data</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-model-py-LC23" class="blob-code blob-code-inner js-file-line">      </td>
        </tr>
        <tr>
          <td id="file-model-py-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-model-py-LC24" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">convolution2D</span>(<span class="pl-s1">image</span>, <span class="pl-s1">kernel</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-model-py-LC25" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Convolve single 2D matrix with kernel using stride</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-model-py-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### returns a single 2D matrix</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-model-py-LC27" class="blob-code blob-code-inner js-file-line">    </td>
        </tr>
        <tr>
          <td id="file-model-py-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-model-py-LC28" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Get dimensions of the input matrix (image) and the kernel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-model-py-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">image_height</span>, <span class="pl-s1">image_width</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">image</span>)), <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">image</span>[<span class="pl-c1">0</span>]))</td>
        </tr>
        <tr>
          <td id="file-model-py-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-model-py-LC30" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">kernel_height</span>, <span class="pl-s1">kernel_width</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">kernel</span>)), <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">kernel</span>[<span class="pl-c1">0</span>]))</td>
        </tr>
        <tr>
          <td id="file-model-py-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-model-py-LC31" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-model-py-LC32" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Calculate dimensions of the output image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-model-py-LC33" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output_height</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_height</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_height</span>) <span class="pl-c1">//</span> <span class="pl-s1">stride</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-model-py-LC34" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output_width</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_width</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_width</span>) <span class="pl-c1">//</span> <span class="pl-s1">stride</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-model-py-LC35" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-model-py-LC36" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Initialize output image with zeros</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-model-py-LC37" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output</span> <span class="pl-c1">=</span> [[<span class="pl-c1">0</span>]<span class="pl-c1">*</span><span class="pl-s1">output_width</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">output_height</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L38" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-model-py-LC38" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L39" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-model-py-LC39" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Iterate over the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L40" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-model-py-LC40" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">0</span>, <span class="pl-s1">image_height</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L41" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-model-py-LC41" class="blob-code blob-code-inner js-file-line">        <span class="pl-c">### optimization</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L42" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-model-py-LC42" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">output_y</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span><span class="pl-c1">//</span><span class="pl-s1">stride</span> </td>
        </tr>
        <tr>
          <td id="file-model-py-L43" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-model-py-LC43" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">j</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">0</span>, <span class="pl-s1">image_width</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L44" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-model-py-LC44" class="blob-code blob-code-inner js-file-line">&#9;        <span class="pl-c">### optimization</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L45" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-model-py-LC45" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">output_x</span> <span class="pl-c1">=</span> <span class="pl-s1">j</span><span class="pl-c1">//</span><span class="pl-s1">stride</span> </td>
        </tr>
        <tr>
          <td id="file-model-py-L46" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-model-py-LC46" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### Check if the kernel can fit in the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L47" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-model-py-LC47" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">if</span> <span class="pl-s1">i</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_height</span> <span class="pl-c1">&lt;=</span> <span class="pl-s1">image_height</span> <span class="pl-c1">and</span> <span class="pl-s1">j</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_width</span> <span class="pl-c1">&lt;=</span> <span class="pl-s1">image_width</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L48" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-model-py-LC48" class="blob-code blob-code-inner js-file-line">                <span class="pl-c">### Apply the kernel to the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L49" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-model-py-LC49" class="blob-code blob-code-inner js-file-line">                <span class="pl-k">for</span> <span class="pl-s1">m</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">kernel_height</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L50" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-model-py-LC50" class="blob-code blob-code-inner js-file-line">                    <span class="pl-s1">i_plus_m</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span><span class="pl-c1">+</span><span class="pl-s1">m</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L51" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-model-py-LC51" class="blob-code blob-code-inner js-file-line">                    <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">kernel_width</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L52" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-model-py-LC52" class="blob-code blob-code-inner js-file-line">                        <span class="pl-s1">output</span>[<span class="pl-s1">output_y</span>][<span class="pl-s1">output_x</span>] <span class="pl-c1">+=</span> <span class="pl-s1">image</span>[<span class="pl-s1">i_plus_m</span>][<span class="pl-s1">j</span><span class="pl-c1">+</span><span class="pl-s1">n</span>] <span class="pl-c1">*</span> <span class="pl-s1">kernel</span>[<span class="pl-s1">m</span>][<span class="pl-s1">n</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L53" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-model-py-LC53" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">output</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc/raw/449f39d8c83143cecd64ebc51277a6fe530165af/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p></p><p>Similarly I've implemented the other layers from my PyTorch model and you can have a look at the code in the appendix. To put all of them together I have a Model class. Let's look at how it works first then we can look at how it's implemented.</p><p>This is how you'd use the Model class.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120147\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>layers_pred</span> <span class=pl-c1>=</span> [<span class=pl-en>convLayer</span>(<span class=pl-c1>1</span>, <span class=pl-c1>3</span>, (<span class=pl-c1>3</span>,<span class=pl-c1>3</span>), <span class=pl-c1>2</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t          <span class=pl-c>### 3 x 6 x 14</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t        <span class=pl-v>ReLU</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>dummyLayer</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>convLayer</span>(<span class=pl-c1>3</span>, <span class=pl-c1>12</span>, (<span class=pl-c1>3</span>,<span class=pl-c1>3</span>), <span class=pl-c1>2</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-c>### 3 x 2 x 6</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-v>ReLU</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>dummyLayer</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>convLayer</span>(<span class=pl-c1>12</span>, <span class=pl-c1>12</span>, (<span class=pl-c1>2</span>,<span class=pl-c1>3</span>), <span class=pl-c1>1</span>),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-c>### 12 x 1 x 4</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-v>ReLU</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>dummyLayer</span>(),               </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-v>Flatten</span>(),</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-en>linearLayer</span>(<span class=pl-c1>48</span>,<span class=pl-c1>7</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>model_name</span> <span class=pl-c1>=</span> <span class=pl-s>&amp;quot;model_weights.json&amp;quot;</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>pred_model</span> <span class=pl-c1>=</span> <span class=pl-v>Model</span>(<span class=pl-s1>layers_pred</span>, <span class=pl-c1>35887.27</span>,<span class=pl-c1>9239.95</span>).<span class=pl-en>load_weights</span>(<span class=pl-s1>model_name</span>)  <span class=pl-c># The two numbers are the mean and standard deviation of the data and they are used to normalize data before feeding it into the model</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/53f4422e0a636688aa0c37a1dd3cf444/raw/de8320feac39d375ac89b4e371502f7ead90e2b5/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/53f4422e0a636688aa0c37a1dd3cf444#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120147" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">layers_pred</span> <span class="pl-c1">=</span> [<span class="pl-en">convLayer</span>(<span class="pl-c1">1</span>, <span class="pl-c1">3</span>, (<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-c1">2</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;          <span class="pl-c">### 3 x 6 x 14</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;        <span class="pl-v">ReLU</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">dummyLayer</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">convLayer</span>(<span class="pl-c1">3</span>, <span class="pl-c1">12</span>, (<span class="pl-c1">3</span>,<span class="pl-c1">3</span>), <span class="pl-c1">2</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">                <span class="pl-c">### 3 x 2 x 6</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">                <span class="pl-v">ReLU</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">dummyLayer</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">convLayer</span>(<span class="pl-c1">12</span>, <span class="pl-c1">12</span>, (<span class="pl-c1">2</span>,<span class="pl-c1">3</span>), <span class="pl-c1">1</span>),</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">                <span class="pl-c">### 12 x 1 x 4</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">                <span class="pl-v">ReLU</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">dummyLayer</span>(),               </td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">                <span class="pl-v">Flatten</span>(),</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">                <span class="pl-en">linearLayer</span>(<span class="pl-c1">48</span>,<span class="pl-c1">7</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model-py-LC16" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">model_name</span> <span class="pl-c1">=</span> <span class="pl-s">"model_weights.json"</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model-py-LC17" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">pred_model</span> <span class="pl-c1">=</span> <span class="pl-v">Model</span>(<span class="pl-s1">layers_pred</span>, <span class="pl-c1">35887.27</span>,<span class="pl-c1">9239.95</span>).<span class="pl-en">load_weights</span>(<span class="pl-s1">model_name</span>)  <span class="pl-c"># The two numbers are the mean and standard deviation of the data and they are used to normalize data before feeding it into the model</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/53f4422e0a636688aa0c37a1dd3cf444/raw/de8320feac39d375ac89b4e371502f7ead90e2b5/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/53f4422e0a636688aa0c37a1dd3cf444#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>And this is how it's implemented - pretty simple.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120171\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-v>Model</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>layers</span>, <span class=pl-s1>inp_norm_mean</span><span class=pl-c1>=</span><span class=pl-c1>0</span>, <span class=pl-s1>inp_norm_sd</span><span class=pl-c1>=</span><span class=pl-c1>1</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>layers</span> <span class=pl-c1>=</span> <span class=pl-s1>layers</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t    <span class=pl-c>### Subtract the mean divide by SD</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>inp_norm</span> <span class=pl-c1>=</span> <span class=pl-k>lambda</span> <span class=pl-s1>inp</span>: <span class=pl-en>normInput</span>(<span class=pl-s1>inp</span>, <span class=pl-c1>1</span><span class=pl-c1>/</span><span class=pl-s1>inp_norm_sd</span>, <span class=pl-c1>-</span><span class=pl-s1>inp_norm_mean</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__getitem__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>i</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-s1>layers</span>[<span class=pl-s1>i</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>out</span> <span class=pl-c1>=</span> <span class=pl-s1>self</span>.<span class=pl-en>inp_norm</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>l</span> <span class=pl-c1>in</span> <span class=pl-s1>self</span>.<span class=pl-s1>layers</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>out</span> <span class=pl-c1>=</span> <span class=pl-en>l</span>(<span class=pl-s1>out</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>out</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e08674d591a6f6a979304cfe58298e3b/raw/2d49a69a7448450fbf38d7ae3a6e769c626b368d/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e08674d591a6f6a979304cfe58298e3b#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120171" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-v">Model</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">layers</span>, <span class="pl-s1">inp_norm_mean</span><span class="pl-c1">=</span><span class="pl-c1">0</span>, <span class="pl-s1">inp_norm_sd</span><span class="pl-c1">=</span><span class="pl-c1">1</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">layers</span> <span class="pl-c1">=</span> <span class="pl-s1">layers</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">&#9;&#9;    <span class="pl-c">### Subtract the mean divide by SD</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">inp_norm</span> <span class="pl-c1">=</span> <span class="pl-k">lambda</span> <span class="pl-s1">inp</span>: <span class="pl-en">normInput</span>(<span class="pl-s1">inp</span>, <span class="pl-c1">1</span><span class="pl-c1">/</span><span class="pl-s1">inp_norm_sd</span>, <span class="pl-c1">-</span><span class="pl-s1">inp_norm_mean</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__getitem__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">i</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-s1">layers</span>[<span class="pl-s1">i</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-s1">self</span>.<span class="pl-en">inp_norm</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">l</span> <span class="pl-c1">in</span> <span class="pl-s1">self</span>.<span class="pl-s1">layers</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-en">l</span>(<span class="pl-s1">out</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">out</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/e08674d591a6f6a979304cfe58298e3b/raw/2d49a69a7448450fbf38d7ae3a6e769c626b368d/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/e08674d591a6f6a979304cfe58298e3b#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>And that's it - we have a working model. We'll need to figure out how to load weights into this next.</p><h2>Load weights</h2><p>PyTorch stores the model weights as a dictionary. Here's an example:</p><pre><code>model_filename = "model_conv_medium_2_300_epochs_bs_5.pt"
state_dict = torch.load(model_filename)
state_dict.keys()
---
output:
---
odict_keys(['0.weight', '0.bias', '2.weight', '2.bias', '4.weight', '4.bias', '7.weight', '7.bias', '9.weight', '9.bias', '11.weight', '11.bias', '13.weight', '13.bias'])
---</code></pre><p>The weights for the model are stored in a dictionary where the keys are <code>{layer_number}.weight</code> or <code>{layer_number}.bias</code>. We save the weights as a JSON file and then write a simple weights loader.</p><p>Here's how we can extend the Model class to load the weights from a JSON file:</p><p>Load the JSON file into a dictionary and go through the layers one at a time. If weights for that layer exist, pass the weights to that layer's <code>load_state_dict</code> function. </p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120207\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-v>Model</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c1>**</span><span class=pl-c1>*</span> <span class=pl-s1>skip</span> <span class=pl-s1>earlier</span> <span class=pl-s1>code</span> <span class=pl-c1>**</span><span class=pl-c1>*</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>def</span> <span class=pl-en>load_weights</span>(<span class=pl-s1>self</span>, <span class=pl-s1>filename</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>with</span> <span class=pl-en>open</span>(<span class=pl-s1>filename</span>) <span class=pl-k>as</span> <span class=pl-s1>f</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>parameters</span> <span class=pl-c1>=</span> <span class=pl-s1>json</span>.<span class=pl-en>load</span>(<span class=pl-s1>f</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>keys</span> <span class=pl-c1>=</span> [<span class=pl-s1>entry</span> <span class=pl-k>for</span> <span class=pl-s1>entry</span> <span class=pl-c1>in</span> <span class=pl-en>sorted</span>(<span class=pl-s1>parameters</span>.<span class=pl-en>keys</span>())]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>layer</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>self</span>.<span class=pl-s1>layers</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-c1>None</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-c1>None</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>if</span> <span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>i</span><span class=pl-kos>}</span></span>.weight&amp;quot;</span> <span class=pl-c1>in</span> <span class=pl-s1>keys</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-s1>parameters</span>[<span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>i</span><span class=pl-kos>}</span></span>.weight&amp;quot;</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>if</span> <span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>i</span><span class=pl-kos>}</span></span>.bias&amp;quot;</span> <span class=pl-c1>in</span> <span class=pl-s1>keys</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>parameters</span>[<span class=pl-s>f&amp;quot;<span class=pl-s1><span class=pl-kos>{</span><span class=pl-s1>i</span><span class=pl-kos>}</span></span>.bias&amp;quot;</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>self</span>.<span class=pl-s1>layers</span>[<span class=pl-s1>i</span>].<span class=pl-en>load_state_dict</span>(<span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/7b2c0172893216f7ab59db7f5cbdc3b6/raw/1d7feea83a622ce8098ffe5ae4e33f6d0b9d7a45/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/7b2c0172893216f7ab59db7f5cbdc3b6#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120207" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-v">Model</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-c1">**</span><span class="pl-c1">*</span> <span class="pl-s1">skip</span> <span class="pl-s1">earlier</span> <span class="pl-s1">code</span> <span class="pl-c1">**</span><span class="pl-c1">*</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">def</span> <span class="pl-en">load_weights</span>(<span class="pl-s1">self</span>, <span class="pl-s1">filename</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">with</span> <span class="pl-en">open</span>(<span class="pl-s1">filename</span>) <span class="pl-k">as</span> <span class="pl-s1">f</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">parameters</span> <span class="pl-c1">=</span> <span class="pl-s1">json</span>.<span class="pl-en">load</span>(<span class="pl-s1">f</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">keys</span> <span class="pl-c1">=</span> [<span class="pl-s1">entry</span> <span class="pl-k">for</span> <span class="pl-s1">entry</span> <span class="pl-c1">in</span> <span class="pl-en">sorted</span>(<span class="pl-s1">parameters</span>.<span class="pl-en">keys</span>())]</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">layer</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">self</span>.<span class="pl-s1">layers</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-c1">None</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-c1">None</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">if</span> <span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">i</span><span class="pl-kos">}</span></span>.weight"</span> <span class="pl-c1">in</span> <span class="pl-s1">keys</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-s1">parameters</span>[<span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">i</span><span class="pl-kos">}</span></span>.weight"</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">if</span> <span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">i</span><span class="pl-kos">}</span></span>.bias"</span> <span class="pl-c1">in</span> <span class="pl-s1">keys</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">parameters</span>[<span class="pl-s">f"<span class="pl-s1"><span class="pl-kos">{</span><span class="pl-s1">i</span><span class="pl-kos">}</span></span>.bias"</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">self</span>.<span class="pl-s1">layers</span>[<span class="pl-s1">i</span>].<span class="pl-en">load_state_dict</span>(<span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/7b2c0172893216f7ab59db7f5cbdc3b6/raw/1d7feea83a622ce8098ffe5ae4e33f6d0b9d7a45/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/7b2c0172893216f7ab59db7f5cbdc3b6#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>Then we need to implement <code>load_state_dict</code> for each layer where we take in the weights and biases and store them for use during inference. </p><p>This is how it works for a linear layer:</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120233\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>linearLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c1>**</span><span class=pl-c1>*</span> <span class=pl-s1>skip</span> <span class=pl-s1>earlier</span> <span class=pl-s1>code</span> <span class=pl-c1>**</span><span class=pl-c1>*</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>def</span> <span class=pl-en>load_state_dict</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-s1>weights</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>bias</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/9e7385e60452ff4fcca0442a54e1b731/raw/902b82b11bfadab1f80e86c9286c9a373b46854a/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/9e7385e60452ff4fcca0442a54e1b731#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120233" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">linearLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-c1">**</span><span class="pl-c1">*</span> <span class="pl-s1">skip</span> <span class="pl-s1">earlier</span> <span class="pl-s1">code</span> <span class="pl-c1">**</span><span class="pl-c1">*</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">def</span> <span class="pl-en">load_state_dict</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-s1">weights</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">bias</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/9e7385e60452ff4fcca0442a54e1b731/raw/902b82b11bfadab1f80e86c9286c9a373b46854a/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/9e7385e60452ff4fcca0442a54e1b731#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>And this is how it works for a convolution layer:</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120241\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>convLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c1>**</span><span class=pl-c1>*</span> <span class=pl-s1>skip</span> <span class=pl-s1>earlier</span> <span class=pl-s1>code</span> <span class=pl-c1>**</span><span class=pl-c1>*</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>def</span> <span class=pl-en>load_state_dict</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>in_channels</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>weights</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>for</span> <span class=pl-s1>j</span>, <span class=pl-s1>kernels</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>in_channels</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>kernel_data</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-k>for</span> <span class=pl-s1>row</span> <span class=pl-c1>in</span> <span class=pl-s1>kernels</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-s1>kernel_data</span>.<span class=pl-en>append</span>(<span class=pl-s1>row</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-s1>kernel_data</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>b</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-s1>b</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/c5cb48c52afe0aed0c29a012641e8ddc/raw/3021919b17432264ba2baa5f11a1985472da897f/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/c5cb48c52afe0aed0c29a012641e8ddc#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120241" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">convLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-c1">**</span><span class="pl-c1">*</span> <span class="pl-s1">skip</span> <span class="pl-s1">earlier</span> <span class="pl-s1">code</span> <span class="pl-c1">**</span><span class="pl-c1">*</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">def</span> <span class="pl-en">load_state_dict</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">in_channels</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">weights</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">for</span> <span class="pl-s1">j</span>, <span class="pl-s1">kernels</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">in_channels</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">kernel_data</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">                <span class="pl-k">for</span> <span class="pl-s1">row</span> <span class="pl-c1">in</span> <span class="pl-s1">kernels</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">                    <span class="pl-s1">kernel_data</span>.<span class="pl-en">append</span>(<span class="pl-s1">row</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-s1">kernel_data</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">b</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-s1">b</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/c5cb48c52afe0aed0c29a012641e8ddc/raw/3021919b17432264ba2baa5f11a1985472da897f/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/c5cb48c52afe0aed0c29a012641e8ddc#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Validate ESP32 output against output from PyTorch model</h2><p>It's pretty important to make sure that the model has the same outputs on an ESP32 and on PyTorch.</p><p>I wrote test scripts with dummy data for each type of layer. Example test for linear layer:</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120271\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-linear_layer_test-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;linear_layer_test.py\&quot;>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>from</span> <span class=pl-s1>model</span> <span class=pl-k>import</span> <span class=pl-s1>linearLayer</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>test_linear_layer</span>(<span class=pl-s1>weights</span>, <span class=pl-s1>biases</span>, <span class=pl-s1>input_data</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Create an instance of the custom LinearLayer class</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>custom_layer</span> <span class=pl-c1>=</span> <span class=pl-en>linearLayer</span>(<span class=pl-s1>weights</span>, <span class=pl-s1>biases</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>custom_output</span> <span class=pl-c1>=</span> <span class=pl-s1>custom_layer</span>.<span class=pl-en>forward</span>(<span class=pl-s1>input_data</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(<span class=pl-s>&amp;quot;Custom Layer Output: &amp;quot;</span>, <span class=pl-s1>custom_output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Create an instance of PyTorch&amp;#39;s nn.Linear class</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>torch_layer</span> <span class=pl-c1>=</span> <span class=pl-s1>nn</span>.<span class=pl-v>Linear</span>(<span class=pl-en>len</span>(<span class=pl-s1>input_data</span>), <span class=pl-en>len</span>(<span class=pl-s1>biases</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>with</span> <span class=pl-s1>torch</span>.<span class=pl-en>no_grad</span>():</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>torch_layer</span>.<span class=pl-s1>weight</span> <span class=pl-c1>=</span> <span class=pl-s1>nn</span>.<span class=pl-v>Parameter</span>(<span class=pl-s1>torch</span>.<span class=pl-en>tensor</span>(<span class=pl-s1>weights</span>).<span class=pl-en>double</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>torch_layer</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>nn</span>.<span class=pl-v>Parameter</span>(<span class=pl-s1>torch</span>.<span class=pl-en>tensor</span>(<span class=pl-s1>biases</span>).<span class=pl-en>double</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>torch_output</span> <span class=pl-c1>=</span> <span class=pl-en>torch_layer</span>(<span class=pl-s1>torch</span>.<span class=pl-en>tensor</span>(<span class=pl-s1>input_data</span>).<span class=pl-en>double</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(<span class=pl-s>&amp;quot;PyTorch Layer Output: &amp;quot;</span>, <span class=pl-s1>torch_output</span>.<span class=pl-en>tolist</span>())</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-c>### Test case 5</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>weights</span> <span class=pl-c1>=</span> [[<span class=pl-c1>0.5</span>, <span class=pl-c1>0.6</span>, <span class=pl-c1>0.7</span>], [<span class=pl-c1>0.8</span>, <span class=pl-c1>0.9</span>, <span class=pl-c1>1.0</span>], [<span class=pl-c1>1.1</span>, <span class=pl-c1>1.2</span>, <span class=pl-c1>1.3</span>]]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>biases</span> <span class=pl-c1>=</span> [<span class=pl-c1>0.9</span>, <span class=pl-c1>1.0</span>, <span class=pl-c1>1.1</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-s1>input_data</span> <span class=pl-c1>=</span> [<span class=pl-c1>1.5</span>, <span class=pl-c1>1.6</span>, <span class=pl-c1>1.7</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-linear_layer_test-py-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-linear_layer_test-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>test_linear_layer</span>(<span class=pl-s1>weights</span>, <span class=pl-s1>biases</span>, <span class=pl-s1>input_data</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/d01e31dd9d0c8432d779cd8d8d6e486b/raw/572ea6e2d90292c8c85f3d7bf86493a5b631e02e/linear_layer_test.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/d01e31dd9d0c8432d779cd8d8d6e486b#file-linear_layer_test-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          linear_layer_test.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120271" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-linear_layer_test-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="linear_layer_test.py">
        <tbody><tr>
          <td id="file-linear_layer_test-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-linear_layer_test-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> <span class="pl-s1">model</span> <span class="pl-k">import</span> <span class="pl-s1">linearLayer</span></td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-linear_layer_test-py-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-linear_layer_test-py-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">test_linear_layer</span>(<span class="pl-s1">weights</span>, <span class="pl-s1">biases</span>, <span class="pl-s1">input_data</span>):</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-linear_layer_test-py-LC4" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Create an instance of the custom LinearLayer class</span></td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-linear_layer_test-py-LC5" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">custom_layer</span> <span class="pl-c1">=</span> <span class="pl-en">linearLayer</span>(<span class="pl-s1">weights</span>, <span class="pl-s1">biases</span>)</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-linear_layer_test-py-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">custom_output</span> <span class="pl-c1">=</span> <span class="pl-s1">custom_layer</span>.<span class="pl-en">forward</span>(<span class="pl-s1">input_data</span>)</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-linear_layer_test-py-LC7" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(<span class="pl-s">"Custom Layer Output: "</span>, <span class="pl-s1">custom_output</span>)</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-linear_layer_test-py-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-linear_layer_test-py-LC9" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Create an instance of PyTorch's nn.Linear class</span></td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-linear_layer_test-py-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">torch_layer</span> <span class="pl-c1">=</span> <span class="pl-s1">nn</span>.<span class="pl-v">Linear</span>(<span class="pl-en">len</span>(<span class="pl-s1">input_data</span>), <span class="pl-en">len</span>(<span class="pl-s1">biases</span>))</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-linear_layer_test-py-LC11" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">with</span> <span class="pl-s1">torch</span>.<span class="pl-en">no_grad</span>():</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-linear_layer_test-py-LC12" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">torch_layer</span>.<span class="pl-s1">weight</span> <span class="pl-c1">=</span> <span class="pl-s1">nn</span>.<span class="pl-v">Parameter</span>(<span class="pl-s1">torch</span>.<span class="pl-en">tensor</span>(<span class="pl-s1">weights</span>).<span class="pl-en">double</span>())</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-linear_layer_test-py-LC13" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">torch_layer</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">nn</span>.<span class="pl-v">Parameter</span>(<span class="pl-s1">torch</span>.<span class="pl-en">tensor</span>(<span class="pl-s1">biases</span>).<span class="pl-en">double</span>())</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-linear_layer_test-py-LC14" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">torch_output</span> <span class="pl-c1">=</span> <span class="pl-en">torch_layer</span>(<span class="pl-s1">torch</span>.<span class="pl-en">tensor</span>(<span class="pl-s1">input_data</span>).<span class="pl-en">double</span>())</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-linear_layer_test-py-LC15" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(<span class="pl-s">"PyTorch Layer Output: "</span>, <span class="pl-s1">torch_output</span>.<span class="pl-en">tolist</span>())</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-linear_layer_test-py-LC16" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-linear_layer_test-py-LC17" class="blob-code blob-code-inner js-file-line"><span class="pl-c">### Test case 5</span></td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-linear_layer_test-py-LC18" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">weights</span> <span class="pl-c1">=</span> [[<span class="pl-c1">0.5</span>, <span class="pl-c1">0.6</span>, <span class="pl-c1">0.7</span>], [<span class="pl-c1">0.8</span>, <span class="pl-c1">0.9</span>, <span class="pl-c1">1.0</span>], [<span class="pl-c1">1.1</span>, <span class="pl-c1">1.2</span>, <span class="pl-c1">1.3</span>]]</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-linear_layer_test-py-LC19" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">biases</span> <span class="pl-c1">=</span> [<span class="pl-c1">0.9</span>, <span class="pl-c1">1.0</span>, <span class="pl-c1">1.1</span>]</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-linear_layer_test-py-LC20" class="blob-code blob-code-inner js-file-line"><span class="pl-s1">input_data</span> <span class="pl-c1">=</span> [<span class="pl-c1">1.5</span>, <span class="pl-c1">1.6</span>, <span class="pl-c1">1.7</span>]</td>
        </tr>
        <tr>
          <td id="file-linear_layer_test-py-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-linear_layer_test-py-LC21" class="blob-code blob-code-inner js-file-line"><span class="pl-en">test_linear_layer</span>(<span class="pl-s1">weights</span>, <span class="pl-s1">biases</span>, <span class="pl-s1">input_data</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/d01e31dd9d0c8432d779cd8d8d6e486b/raw/572ea6e2d90292c8c85f3d7bf86493a5b631e02e/linear_layer_test.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/d01e31dd9d0c8432d779cd8d8d6e486b#file-linear_layer_test-py" class="Link--inTextBlock">
          linear_layer_test.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>The really nice thing about using MicroPython is that I can import code that is supposed to run on my ESP32 into regular old desktop Python and execute it to validate it. That's what the <code>from model import linearLayer</code> line is doing - importing MicroPython code into desktop Python since it's also perfectly valid desktop Python code. The ability to develop like this makes MicroPython extremely powerful.</p><p>Similarly, I picked one datapoint  from my dataset and ran it through each model I was testing to make sure the output of the model on MicroPython matches the output of the original PyTorch model for that datapoint.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120291\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model_test-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model_test.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model_test-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>from</span> <span class=pl-s1>model</span> <span class=pl-k>import</span> <span class=pl-c1>*</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-s1>random</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>from</span> <span class=pl-s1>single_datapoint_for_testing</span> <span class=pl-k>import</span> <span class=pl-c1>*</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-s1>time</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>import</span> <span class=pl-s1>sys</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>if</span> <span class=pl-s1>sys</span>.<span class=pl-s1>implementation</span>.<span class=pl-s1>name</span> <span class=pl-c1>!=</span> <span class=pl-s>&amp;quot;micropython&amp;quot;</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### I run this on both desktop python and micropython</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### but desktop python doesn&amp;#39;t have ticks_ms so I use time.time instead</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>time</span>.<span class=pl-s1>ticks_ms</span> <span class=pl-c1>=</span> <span class=pl-s1>time</span>.<span class=pl-s1>time</span> </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>testModel</span>(<span class=pl-s1>model</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>start_time</span> <span class=pl-c1>=</span> <span class=pl-s1>time</span>.<span class=pl-en>ticks_ms</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>out</span> <span class=pl-c1>=</span> <span class=pl-en>model</span>(<span class=pl-s1>single_data_point</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>end_time</span> <span class=pl-c1>=</span> <span class=pl-s1>time</span>.<span class=pl-en>ticks_ms</span>()</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(<span class=pl-s1>end_time</span><span class=pl-c1>-</span><span class=pl-s1>start_time</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>print</span>(<span class=pl-s1>out</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model_test-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-model_test-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>testModel</span>(<span class=pl-s1>pred_model</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/c841c3c6be6043a0704225bfd2ddb4dd/raw/1420188e2cdda139977d0474a33be3c92f9d03f7/model_test.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/c841c3c6be6043a0704225bfd2ddb4dd#file-model_test-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model_test.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120291" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model_test-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model_test.py">
        <tbody><tr>
          <td id="file-model_test-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model_test-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> <span class="pl-s1">model</span> <span class="pl-k">import</span> <span class="pl-c1">*</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model_test-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">random</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model_test-py-LC3" class="blob-code blob-code-inner js-file-line"><span class="pl-k">from</span> <span class="pl-s1">single_datapoint_for_testing</span> <span class="pl-k">import</span> <span class="pl-c1">*</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model_test-py-LC4" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">time</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model_test-py-LC5" class="blob-code blob-code-inner js-file-line"><span class="pl-k">import</span> <span class="pl-s1">sys</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model_test-py-LC6" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model_test-py-LC7" class="blob-code blob-code-inner js-file-line"><span class="pl-k">if</span> <span class="pl-s1">sys</span>.<span class="pl-s1">implementation</span>.<span class="pl-s1">name</span> <span class="pl-c1">!=</span> <span class="pl-s">"micropython"</span>:</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model_test-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### I run this on both desktop python and micropython</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model_test-py-LC9" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### but desktop python doesn't have ticks_ms so I use time.time instead</span></td>
        </tr>
        <tr>
          <td id="file-model_test-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model_test-py-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">time</span>.<span class="pl-s1">ticks_ms</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-s1">time</span> </td>
        </tr>
        <tr>
          <td id="file-model_test-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model_test-py-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model_test-py-LC12" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">testModel</span>(<span class="pl-s1">model</span>):</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model_test-py-LC13" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">start_time</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-en">ticks_ms</span>()</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model_test-py-LC14" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">out</span> <span class="pl-c1">=</span> <span class="pl-en">model</span>(<span class="pl-s1">single_data_point</span>)</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model_test-py-LC15" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">end_time</span> <span class="pl-c1">=</span> <span class="pl-s1">time</span>.<span class="pl-en">ticks_ms</span>()</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model_test-py-LC16" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(<span class="pl-s1">end_time</span><span class="pl-c1">-</span><span class="pl-s1">start_time</span>)</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model_test-py-LC17" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">print</span>(<span class="pl-s1">out</span>)</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-model_test-py-LC18" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model_test-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-model_test-py-LC19" class="blob-code blob-code-inner js-file-line"><span class="pl-en">testModel</span>(<span class="pl-s1">pred_model</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/c841c3c6be6043a0704225bfd2ddb4dd/raw/1420188e2cdda139977d0474a33be3c92f9d03f7/model_test.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/c841c3c6be6043a0704225bfd2ddb4dd#file-model_test-py" class="Link--inTextBlock">
          model_test.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>These tests were especially helpful later when I was writing C optimisations - I just had to rerun the tests to make sure I didn't break anything.</p><p>Output from benchmark_model (not the same as our final inference model) used during development that was run on PyTorch:</p><pre><code><code>tensor([-309.3656,   66.2828,  -38.7419,  -72.0498], grad_fn=&lt;AddBackward0&gt;)
</code></code></pre><p>Output from benchmark_model used during development that was run on ESP32:</p><pre><code><code>[-309.3655, 66.28277, -38.74186, -72.04981]
</code></code></pre><p>For anyone wondering why the outputs don't match exactly eg. -309.3656 vs -309.3655 - this is because of small errors that are inherent to floating point calculations on GPUs partially due to limitations of floating point numbers and partially due GPUs preferring speed over absolute accuracy so they make optimisations that get "close enough" return values but get them faster.</p><p>Here's an example where desktop Python gets a floating point calculation slightly wrong:</p><pre><code><code>&gt;&gt;&gt; 0.7+0.6
1.2999999999999998
</code></code></pre><p>Correct answer is:</p><pre><code><code>1.3
</code></code></pre><p>So the answer is off by 0.0000000000000002.</p><p>But interestingly enough if you do the same calculation but break it up, you get the "correct" answer:</p><pre><code><code>&gt;&gt;&gt; 0.2+0.2+0.2+0.7
1.3
# Even this isn't entirely correct - the actual value in floating point notation is 5854679515581645 / 4503599627370496 which translates to around 1.300000000000000044408920985 - but Python truncates it to 1.3 for display purposes
</code></code></pre><p>This is because in floating point operations, the order of operations matters because each number is just an approximate representation of the true value. As you stack more calculations up the errors get larger.</p><p>Does it matter? These types of errors can cause issues during training but not so much during inference so for now we can safely ignore it.</p><h2>Performance optimization</h2><p>Inference on the benchmark model I was initially using for testing took 194ms. Is that good enough? Maybe. Depends on the use case. But being faster would make this a lot more useful across other embedded use cases and honestly optimization is just fun. Perks of this being on my blog rather than in a product is I can do it just because I want to.</p><p>For performance optimization you definitely want to start with a target. Mine was to have inference complete in less than 50ms because that means that you could run inference realtime if you wanted since you collect data every 50ms.</p><p>There are three approaches to speeding up inference:</p><ul><li><p>Rewrite specific function calls in C.</p><ul><li><p>eg. the Convolution2D function that convolves a single 2D matrix is a great candidate to be rewritten in C because that has a bunch of loops and rewriting it in C still allows us to retain all of the flexibility of python since we can continue to restructure our model while just calling the function as if it were any other Python function.</p></li><li><p>There are a few other functions like this that I'll talk about later in the article as well as the exact impact they had on execution time.</p></li><li><p>The rewritten C functions were compiled as a <a href="https://docs.micropython.org/en/latest/develop/natmod.html">native module</a> called "mlops" which is a collection of operations useful for machine learning applications. A native module is essentially just a library but compiled into a binary rather than Python code. I upload the "mlops.mpy" library onto the ESP32 like any other MicroPython file and can use it as a module by importing it like any other module with <code>import mlops</code></p></li></ul></li><li><p>The second approach is to do inference entirely in C and just call the model from MicroPython eg. <code>c_model.predict(data)</code>. This would definitely be the fastest but least flexible - I'd have to rewrite and recompile the C module each time I change model architecture.</p></li><li><p>The third approach is to apply application specific optimizations'. eg. if I was to predict gestures each time a datapoint is collected (every 50ms) then only the last entry of the 1.5s long data recording would change so I just need to update calculations that depend on the last row.</p></li></ul><p></p><p>For my use case (a proof of concept on a for-fun blog) I felt the first type of optimization was good enough. I can just predict once every 1.5s and it still works fine.</p><p>So now we need to rewrite specific Python functions in C. Let's look at rewriting the the ReLU function in C. As a quick refresher ReLU is a function that replaces all negative elements of a matrix with 0 and leaves the positive elements untouched.</p><p>The original Python version is:</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120313\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>reluConv</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### In case anyone is wondering why I&amp;#39;ve wrapped </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### forward in __call__ - it&amp;#39;s because when I am  </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### profiling I only want to know the execution time</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### for the full relu call, not for each layer of the recursive call</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>if</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>output</span>, <span class=pl-s1>list</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>return</span> [<span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>i</span>) <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-s1>output</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>else</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>return</span> <span class=pl-en>max</span>(<span class=pl-c1>0</span>, <span class=pl-s1>output</span>) </td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d/raw/84670b974c3b7aca7daff08a6ff1987d9796303a/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120313" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">reluConv</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### In case anyone is wondering why I've wrapped </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### forward in __call__ - it's because when I am  </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### profiling I only want to know the execution time</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### for the full relu call, not for each layer of the recursive call</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">output</span>, <span class="pl-s1">list</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">return</span> [<span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">i</span>) <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-s1">output</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">else</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">return</span> <span class="pl-en">max</span>(<span class="pl-c1">0</span>, <span class="pl-s1">output</span>) </td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d/raw/84670b974c3b7aca7daff08a6ff1987d9796303a/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>The C optimized forward function is below.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120331\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>relu</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>input</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// Check if input is a list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>if</span> (<span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_list</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Create a new list to hold relu-ed values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>outputs</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-c1>0</span>, <span class=pl-c1>NULL</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert input list to pointer and get length</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>input_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>unsigned <span class=pl-smi>int</span></span> <span class=pl-s1>list_len</span> <span class=pl-c1>=</span> <span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>list_len</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// relu each item in input list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-en>relu</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// append to new list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t  <span class=pl-en>mp_obj_list_append</span>(<span class=pl-s1>outputs</span>, <span class=pl-s1>output</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>outputs</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  } <span class=pl-k>else</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// relu the scalar input </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_float_t</span> <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> (<span class=pl-s1>output</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-c1>0</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-en>mp_obj_new_float</span>(<span class=pl-s1>output</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef/raw/e98b6ab47f2bb66cdefcef388482041f2af5377d/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120331" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">relu</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">input</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// Check if input is a list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">if</span> (<span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_list</span>)) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Create a new list to hold relu-ed values</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">outputs</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-c1">0</span>, <span class="pl-c1">NULL</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert input list to pointer and get length</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">input_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">unsigned <span class="pl-smi">int</span></span> <span class="pl-s1">list_len</span> <span class="pl-c1">=</span> <span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">list_len</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// relu each item in input list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">      <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-en">relu</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// append to new list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">&#9;  <span class="pl-en">mp_obj_list_append</span>(<span class="pl-s1">outputs</span>, <span class="pl-s1">output</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">outputs</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">  } <span class="pl-k">else</span> {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// relu the scalar input </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_float_t</span> <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> (<span class="pl-s1">output</span> <span class="pl-c1">&lt;</span> <span class="pl-c1">0</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">      <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-en">mp_obj_new_float</span>(<span class="pl-s1">output</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-mlops-c-LC32" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-mlops-c-LC33" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef/raw/e98b6ab47f2bb66cdefcef388482041f2af5377d/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>And after we compile that and load the new <code>mlops.mpy</code> library, we rewrite the python class as shown below. This is why I love this approach - it's a really happy medium between having the development speed of Python and the runtime execution speed of C.</p><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120342\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>reluConv</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>relu</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857/raw/6b3170e2a6fe429ae05c2feaad6c8384e968a8d2/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120342" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">reluConv</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">relu</span>(<span class="pl-s1">output</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857/raw/6b3170e2a6fe429ae05c2feaad6c8384e968a8d2/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><p>Here is a list of performance optimizations. All measurements below were taken at 160MHz clock speed because that's what I started off with and later figured I'll consider the speed increase from the switch to 240MHz during inference as "margin of error" in case things go wrong. I'm glad I did that since I later had to increase model size and therefore it took longer to compute but I was still under my 50ms criteria.</p><p>Here are the optimizations and then a chart showing how much time each optimization saved.</p><ul><li><p>194ms was the original inference time</p></li><li><p>138ms after using the <a href="https://docs.micropython.org/en/latest/reference/speed_python.html#the-native-code-emitter">native code emitter</a> in micropython (out of which 56ms/40% of the time is spent in the Convolution2D function)</p></li><li><p>129ms after specific small performance optimizations (eg. cache values in loops, flatten in C)</p></li><li><p>74ms after Convolution2D implemented in C</p></li><li><p>66ms after ReLU forward call implemented in C</p></li><li><p>49ms after linearLayer matrix multiplication implemented in C</p></li><li><p>32ms after implementing a matrix summation function in C</p></li><li><p>21ms after changing the input normalization function to C</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Qy3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Qy3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 424w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 848w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 1272w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Qy3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png" width="849" height="636" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:636,&quot;width&quot;:849,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:14849,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0Qy3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 424w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 848w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 1272w, https://substackcdn.com/image/fetch/$s_!0Qy3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895c4884-0965-4d00-bdf2-560ea3ef754f_849x636.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>These optimizations brought inference time down from 194ms to 23ms @ 160MHz. Inference time was 15ms @ 240MHz. </p><p>After I switched to a bigger model inference took 31ms @ 240MHz. If you call this once every 1.5s that's just using 2% of one of the two cores on the ESP32. Plenty of cycles left to do lots of other stuff.</p><h1>Side Notes</h1><p>Here's a few small asides.</p><h2>How many samples are needed?</h2><p>I looked into whether I really needed 120 samples for each gesture and it does seem like it's roughly correct. Here is model accuracy vs number of samples. These were trained for 2 minutes (50 epochs with one cycle LR scheduler) rather than 13 minutes.</p><p>It looks like 75 samples may be enough too but went with higher just to be safe - 96 training samples and 24 validation samples (120 total).</p><p>Note: I don't think the slight drop from 75 to 100 is significant, with more runs to sample I feel like it would likely cancel out. From a decision making perspective - 75 or 100 both are probably fine and 100 is safer.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Wto!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Wto!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 424w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 848w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 1272w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Wto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png" width="1456" height="471" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:471,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:54849,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-Wto!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 424w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 848w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 1272w, https://substackcdn.com/image/fetch/$s_!-Wto!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0502fae4-74bf-4f0a-82c9-0742f0823272_1677x542.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Using coins while I was waiting for the PCB to arrive</h2><p>After I had the idea to try this and before I received the touch pad PCBs I sent to get made I wanted to carry on with the firmware and software development so I soldered a bunch of coins and put them in a 3D printed casing to start working on the software while I wait for the hardware. It was too big and didn't feel good to "write" on but definitely fun to use coins as touch sensors!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F9TJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F9TJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 424w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 848w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 1272w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F9TJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png" width="1456" height="746" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:746,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1729304,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!F9TJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 424w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 848w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 1272w, https://substackcdn.com/image/fetch/$s_!F9TJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F361ac3f0-1a37-4465-9789-c3274029a523_1777x910.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Confidence Threshold</h2><ul><li><p>On the ESP32 after the model makes a prediction I only allow it to update the display if it is at least 75% confident that the answer is correct. This does two things:</p><ul><li><p>Prevents it from interpreting ambiguous signals like my palm resting on the touchpad as an alphabet</p></li><li><p>If it sees an alphabet drawn in a way that confuses the model, it prevents the model from forcing a guess - I found it was often wrong with these types of guesses. It must be quite confident about the prediction to display it on the screen.</p></li></ul></li></ul><h2>Libraries</h2><p>I tried to look at other libraries like ndarray or upytorch but none of them could do what I needed yet:</p><ul><li><p><a href="https://github.com/ljk53/upytorch">uPyTorch</a> doesn't have inference yet </p></li><li><p><a href="https://github.com/v923z/micropython-ulab">ndarray</a> actually made things slower - code that was pure MicroPython with native emitter that took 138ms to run without ndarray took 179ms after using ndarray. </p></li></ul><h1>Appendix - All the other layers</h1><p>Earlier in the article I mentioned I would show the code for all the other layers - so I've put the code down here along with their C equivalents.</p><h2>Linear Layer</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120366\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>linearLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Initialize weights and bias with given values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-s1>weights</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>bias</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>input_data</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-s1>intermediate_output</span> <span class=pl-c1>=</span> [<span class=pl-c1>0</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>weights</span>))]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>weights</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>for</span> <span class=pl-s1>j</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>weights</span>[<span class=pl-c1>0</span>])):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                 <span class=pl-s1>intermediate_output</span>[<span class=pl-s1>i</span>] <span class=pl-c1>+=</span> <span class=pl-s1>self</span>.<span class=pl-s1>weights</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>*</span> <span class=pl-s1>input_data</span>[<span class=pl-s1>j</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-c># Add bias</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-s1>output_data</span> <span class=pl-c1>=</span> [<span class=pl-s1>intermediate_output</span>[<span class=pl-s1>i</span>] <span class=pl-c1>+</span> <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>i</span>] <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>bias</span>))]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>output_data</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/1828e34e8d02148921af3a38459ef54c/raw/25dafdc1cee4b2ae7246b7c308a9eaa3a9a7a2d2/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/1828e34e8d02148921af3a38459ef54c#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120366" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">linearLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Initialize weights and bias with given values</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-s1">weights</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">bias</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">input_data</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">         <span class="pl-s1">intermediate_output</span> <span class="pl-c1">=</span> [<span class="pl-c1">0</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">weights</span>))]</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">weights</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">for</span> <span class="pl-s1">j</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">weights</span>[<span class="pl-c1">0</span>])):</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">                 <span class="pl-s1">intermediate_output</span>[<span class="pl-s1">i</span>] <span class="pl-c1">+=</span> <span class="pl-s1">self</span>.<span class="pl-s1">weights</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">*</span> <span class="pl-s1">input_data</span>[<span class="pl-s1">j</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">         <span class="pl-c"># Add bias</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">         <span class="pl-s1">output_data</span> <span class="pl-c1">=</span> [<span class="pl-s1">intermediate_output</span>[<span class="pl-s1">i</span>] <span class="pl-c1">+</span> <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">i</span>] <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">bias</span>))]</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">output_data</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/1828e34e8d02148921af3a38459ef54c/raw/25dafdc1cee4b2ae7246b7c308a9eaa3a9a7a2d2/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/1828e34e8d02148921af3a38459ef54c#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Linear Layer with C Optimization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120373\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>linearLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c># Initialize weights and bias with given values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-s1>weights</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>bias</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>input_data</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>linear</span>(<span class=pl-s1>input_data</span>, <span class=pl-s1>self</span>.<span class=pl-s1>weights</span>, <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>load_state_dict</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>weights</span> <span class=pl-c1>=</span> <span class=pl-s1>weights</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> <span class=pl-s1>bias</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/91f0fc5d5d779e4347c9ad3024a4d428/raw/9a06b5815657aa7554c2350c0cd60697c8eacc64/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/91f0fc5d5d779e4347c9ad3024a4d428#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120373" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">linearLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-c"># Initialize weights and bias with given values</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-s1">weights</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">bias</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">input_data</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">linear</span>(<span class="pl-s1">input_data</span>, <span class="pl-s1">self</span>.<span class="pl-s1">weights</span>, <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">load_state_dict</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">weights</span> <span class="pl-c1">=</span> <span class="pl-s1">weights</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> <span class="pl-s1">bias</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/91f0fc5d5d779e4347c9ad3024a4d428/raw/9a06b5815657aa7554c2350c0cd60697c8eacc64/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/91f0fc5d5d779e4347c9ad3024a4d428#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120388\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>linear</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>input_data</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>weights</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>bias</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert from mpy lists to pointers</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>input_data_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>input_data</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>weights_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>weights</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>weights_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>weights_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-c1>0</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>bias_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>bias</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>int</span> <span class=pl-s1>weights_height</span> <span class=pl-c1>=</span> <span class=pl-s1>weights_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;<span class=pl-c>//24, running through 48 inp features 24 outp features in comments as an example</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>int</span> <span class=pl-s1>weights_width</span> <span class=pl-c1>=</span> <span class=pl-s1>weights_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;<span class=pl-c>//48</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert data to float</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>input_data_f</span>[<span class=pl-s1>weights_width</span>];<span class=pl-c>//48</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_width</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>input_data_f</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>input_data_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>weights_f</span>[<span class=pl-s1>weights_height</span>][<span class=pl-s1>weights_width</span>];<span class=pl-c>//weights_f[24][48]</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>weights_vector</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){<span class=pl-c>//24</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>weights_vector</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>weights_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);\t\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){<span class=pl-c>//48</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>weights_f</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>weights_vector</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>j</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Create array of zeroes </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>output</span>[<span class=pl-s1>weights_height</span>];</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {<span class=pl-c>//24</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>output</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-en>mp_obj_new_float</span>(<span class=pl-c1>0.0</span>));<span class=pl-c>//weird workaround for linker bug </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Calculate result</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {<span class=pl-c>//0 to 24 </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>) {<span class=pl-c>//0 to 48</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>output</span>[<span class=pl-s1>i</span>] <span class=pl-c1>+=</span> <span class=pl-s1>weights_f</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>*</span> <span class=pl-s1>input_data_f</span>[<span class=pl-s1>j</span>];</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L38\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L39\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Add bias</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L40\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L41\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>output</span>[<span class=pl-s1>i</span>] <span class=pl-c1>+=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>bias_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]); </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L42\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L43\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L44\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert to mpy</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L45\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>weights_height</span>];<span class=pl-c>//store lists of rows in this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L46\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>weights_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L47\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_float</span>(<span class=pl-s1>output</span>[<span class=pl-s1>i</span>]);<span class=pl-c>//convert row to mp list and store into array</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L48\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L49\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-s1>weights_height</span>, <span class=pl-s1>output_converted_to_mp</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L50\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/ef8d6fdc916a054f4634fdd957ef786b/raw/0d6af0d0d4dfc64ca40f29af2fea53c0b013e619/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/ef8d6fdc916a054f4634fdd957ef786b#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120388" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">linear</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">input_data</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">weights</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">bias</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert from mpy lists to pointers</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">input_data_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">input_data</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">weights_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">weights</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">weights_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">weights_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-c1">0</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">bias_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">bias</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">int</span> <span class="pl-s1">weights_height</span> <span class="pl-c1">=</span> <span class="pl-s1">weights_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;<span class="pl-c">//24, running through 48 inp features 24 outp features in comments as an example</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">int</span> <span class="pl-s1">weights_width</span> <span class="pl-c1">=</span> <span class="pl-s1">weights_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;<span class="pl-c">//48</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert data to float</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">input_data_f</span>[<span class="pl-s1">weights_width</span>];<span class="pl-c">//48</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_width</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">input_data_f</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">input_data_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">weights_f</span>[<span class="pl-s1">weights_height</span>][<span class="pl-s1">weights_width</span>];<span class="pl-c">//weights_f[24][48]</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">weights_vector</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){<span class="pl-c">//24</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">weights_vector</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">weights_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);&#9;&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){<span class="pl-c">//48</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">weights_f</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">weights_vector</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">j</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Create array of zeroes </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">output</span>[<span class="pl-s1">weights_height</span>];</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {<span class="pl-c">//24</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">output</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-en">mp_obj_new_float</span>(<span class="pl-c1">0.0</span>));<span class="pl-c">//weird workaround for linker bug </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Calculate result</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-mlops-c-LC32" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {<span class="pl-c">//0 to 24 </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-mlops-c-LC33" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>) {<span class="pl-c">//0 to 48</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-mlops-c-LC34" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">output</span>[<span class="pl-s1">i</span>] <span class="pl-c1">+=</span> <span class="pl-s1">weights_f</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">*</span> <span class="pl-s1">input_data_f</span>[<span class="pl-s1">j</span>];</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-mlops-c-LC35" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-mlops-c-LC36" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-mlops-c-LC37" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L38" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-mlops-c-LC38" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L39" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-mlops-c-LC39" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Add bias</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L40" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-mlops-c-LC40" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L41" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-mlops-c-LC41" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">output</span>[<span class="pl-s1">i</span>] <span class="pl-c1">+=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">bias_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]); </td>
        </tr>
        <tr>
          <td id="file-mlops-c-L42" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-mlops-c-LC42" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L43" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-mlops-c-LC43" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L44" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-mlops-c-LC44" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert to mpy</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L45" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-mlops-c-LC45" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">weights_height</span>];<span class="pl-c">//store lists of rows in this</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L46" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-mlops-c-LC46" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">weights_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L47" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-mlops-c-LC47" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_float</span>(<span class="pl-s1">output</span>[<span class="pl-s1">i</span>]);<span class="pl-c">//convert row to mp list and store into array</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L48" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-mlops-c-LC48" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L49" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-mlops-c-LC49" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-s1">weights_height</span>, <span class="pl-s1">output_converted_to_mp</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L50" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-mlops-c-LC50" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/ef8d6fdc916a054f4634fdd957ef786b/raw/0d6af0d0d4dfc64ca40f29af2fea53c0b013e619/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/ef8d6fdc916a054f4634fdd957ef786b#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>ReLU Layer</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120313\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>reluConv</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### In case anyone is wondering why I&amp;#39;ve wrapped </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### forward in __call__ - it&amp;#39;s because when I am  </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### profiling I only want to know the execution time</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>### for the full relu call, not for each layer of the recursive call</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>if</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>output</span>, <span class=pl-s1>list</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>return</span> [<span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>i</span>) <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-s1>output</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>else</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>return</span> <span class=pl-en>max</span>(<span class=pl-c1>0</span>, <span class=pl-s1>output</span>) </td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d/raw/84670b974c3b7aca7daff08a6ff1987d9796303a/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120313" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">reluConv</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### In case anyone is wondering why I've wrapped </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### forward in __call__ - it's because when I am  </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### profiling I only want to know the execution time</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">### for the full relu call, not for each layer of the recursive call</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">output</span>, <span class="pl-s1">list</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">return</span> [<span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">i</span>) <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-s1">output</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">else</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">return</span> <span class="pl-en">max</span>(<span class="pl-c1">0</span>, <span class="pl-s1">output</span>) </td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d/raw/84670b974c3b7aca7daff08a6ff1987d9796303a/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/8b6115fb46e5addb7f07fb1b008ad93d#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>ReLU Layer with C Optimization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120342\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>reluConv</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>     <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>relu</span>(<span class=pl-s1>output</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857/raw/6b3170e2a6fe429ae05c2feaad6c8384e968a8d2/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120342" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">reluConv</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">     <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">relu</span>(<span class="pl-s1">output</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857/raw/6b3170e2a6fe429ae05c2feaad6c8384e968a8d2/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/6b77540e14baa12369fa12e5d62ab857#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120331\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>relu</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>input</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// Check if input is a list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>if</span> (<span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_list</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Create a new list to hold relu-ed values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>outputs</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-c1>0</span>, <span class=pl-c1>NULL</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert input list to pointer and get length</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>input_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>unsigned <span class=pl-smi>int</span></span> <span class=pl-s1>list_len</span> <span class=pl-c1>=</span> <span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>list_len</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// relu each item in input list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-en>relu</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// append to new list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t  <span class=pl-en>mp_obj_list_append</span>(<span class=pl-s1>outputs</span>, <span class=pl-s1>output</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>outputs</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  } <span class=pl-k>else</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// relu the scalar input </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_float_t</span> <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>if</span> (<span class=pl-s1>output</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-c1>0</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-s1>output</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-en>mp_obj_new_float</span>(<span class=pl-s1>output</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef/raw/e98b6ab47f2bb66cdefcef388482041f2af5377d/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120331" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">relu</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">input</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// Check if input is a list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">if</span> (<span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_list</span>)) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Create a new list to hold relu-ed values</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">outputs</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-c1">0</span>, <span class="pl-c1">NULL</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert input list to pointer and get length</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">input_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">unsigned <span class="pl-smi">int</span></span> <span class="pl-s1">list_len</span> <span class="pl-c1">=</span> <span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">list_len</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// relu each item in input list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">      <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-en">relu</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// append to new list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">&#9;  <span class="pl-en">mp_obj_list_append</span>(<span class="pl-s1">outputs</span>, <span class="pl-s1">output</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">outputs</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">  } <span class="pl-k">else</span> {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// relu the scalar input </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_float_t</span> <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">if</span> (<span class="pl-s1">output</span> <span class="pl-c1">&lt;</span> <span class="pl-c1">0</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">      <span class="pl-s1">output</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-en">mp_obj_new_float</span>(<span class="pl-s1">output</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-mlops-c-LC32" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-mlops-c-LC33" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef/raw/e98b6ab47f2bb66cdefcef388482041f2af5377d/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/104424901ec414a03f05e62f181e69ef#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Dummy Layer</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120460\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-v>Module</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>load_state_dict</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>pass</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>dummyLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>output</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>output</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/45e83ee06fcd8f9b205adf41d8b686e0/raw/78c251896ab69d822f9274ea26092653caf65d4c/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/45e83ee06fcd8f9b205adf41d8b686e0#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120460" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-v">Module</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">load_state_dict</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">pass</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">dummyLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">output</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">output</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/45e83ee06fcd8f9b205adf41d8b686e0/raw/78c251896ab69d822f9274ea26092653caf65d4c/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/45e83ee06fcd8f9b205adf41d8b686e0#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Flatten Layer</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120475\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-v>Flatten</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>if</span> <span class=pl-c1>not</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>inp</span>, (<span class=pl-s1>list</span>, <span class=pl-s1>tuple</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>return</span> [<span class=pl-s1>inp</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-s1>result</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-s1>inp</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>if</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>i</span>, (<span class=pl-s1>list</span>, <span class=pl-s1>tuple</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                 <span class=pl-s1>result</span>.<span class=pl-en>extend</span>(<span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>i</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>             <span class=pl-k>else</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                 <span class=pl-s1>result</span>.<span class=pl-en>append</span>(<span class=pl-s1>i</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>         <span class=pl-k>return</span> <span class=pl-s1>result</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/68174c97b95ad6f27e7d7da4bf029a90/raw/fac8580c2985375801c6c3c11ad30fb13129a894/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/68174c97b95ad6f27e7d7da4bf029a90#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120475" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-v">Flatten</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">if</span> <span class="pl-c1">not</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">inp</span>, (<span class="pl-s1">list</span>, <span class="pl-s1">tuple</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">return</span> [<span class="pl-s1">inp</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">         <span class="pl-s1">result</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-s1">inp</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">i</span>, (<span class="pl-s1">list</span>, <span class="pl-s1">tuple</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">                 <span class="pl-s1">result</span>.<span class="pl-en">extend</span>(<span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">i</span>))</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">             <span class="pl-k">else</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">                 <span class="pl-s1">result</span>.<span class="pl-en">append</span>(<span class="pl-s1">i</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">         <span class="pl-k">return</span> <span class="pl-s1">result</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/68174c97b95ad6f27e7d7da4bf029a90/raw/fac8580c2985375801c6c3c11ad30fb13129a894/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/68174c97b95ad6f27e7d7da4bf029a90#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Flatten Layer with C Optimization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120485\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-v>Flatten</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>self</span>.<span class=pl-en>forward</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>forward</span>(<span class=pl-s1>self</span>, <span class=pl-s1>inp</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>flatten</span>(<span class=pl-s1>inp</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/9a13fa456ad3efca1055bf9ad4f5dba6/raw/796c8ca36a40079fcd46fd132afd264cdcc080dc/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/9a13fa456ad3efca1055bf9ad4f5dba6#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120485" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-v">Flatten</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">self</span>.<span class="pl-en">forward</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">forward</span>(<span class="pl-s1">self</span>, <span class="pl-s1">inp</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">flatten</span>(<span class="pl-s1">inp</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/9a13fa456ad3efca1055bf9ad4f5dba6/raw/796c8ca36a40079fcd46fd132afd264cdcc080dc/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/9a13fa456ad3efca1055bf9ad4f5dba6#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120495\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>flatten</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>input</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// Check if input is a list or tuple</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>if</span> (<span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_list</span>) <span class=pl-c1>||</span> <span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_tuple</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Create a new list to hold flattened values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>outputs</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-c1>0</span>, <span class=pl-c1>NULL</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Convert input list to pointer and get length</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>input_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>unsigned <span class=pl-smi>int</span></span> <span class=pl-s1>list_len</span> <span class=pl-c1>=</span> <span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>list_len</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-c>// Check if item is a list or tuple</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-k>if</span> (<span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>], <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_list</span>) <span class=pl-c1>||</span> <span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>], <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_tuple</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c>// Flatten the item and extend the output list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>flattened</span> <span class=pl-c1>=</span> <span class=pl-en>flatten</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>flattened_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>flattened</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>flattened_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>          <span class=pl-en>mp_obj_list_append</span>(<span class=pl-s1>outputs</span>, <span class=pl-s1>flattened_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>j</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      } <span class=pl-k>else</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c>// Append the item to the output list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-en>mp_obj_list_append</span>(<span class=pl-s1>outputs</span>, <span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>outputs</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  } <span class=pl-k>else</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Return the scalar input as a list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-c1>1</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/dbcf7f02d924f780477fac2a196eabbe/raw/50e77f51c4b8129aa23199e94558543488387900/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/dbcf7f02d924f780477fac2a196eabbe#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120495" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">flatten</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">input</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// Check if input is a list or tuple</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">if</span> (<span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_list</span>) <span class="pl-c1">||</span> <span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_tuple</span>)) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Create a new list to hold flattened values</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">outputs</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-c1">0</span>, <span class="pl-c1">NULL</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Convert input list to pointer and get length</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">input_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">unsigned <span class="pl-smi">int</span></span> <span class="pl-s1">list_len</span> <span class="pl-c1">=</span> <span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">list_len</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">      <span class="pl-c">// Check if item is a list or tuple</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">      <span class="pl-k">if</span> (<span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>], <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_list</span>) <span class="pl-c1">||</span> <span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>], <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_tuple</span>)) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">        <span class="pl-c">// Flatten the item and extend the output list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">        <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">flattened</span> <span class="pl-c1">=</span> <span class="pl-en">flatten</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">        <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">flattened_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">flattened</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">flattened_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">          <span class="pl-en">mp_obj_list_append</span>(<span class="pl-s1">outputs</span>, <span class="pl-s1">flattened_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">j</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">        }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">      } <span class="pl-k">else</span> {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">        <span class="pl-c">// Append the item to the output list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">        <span class="pl-en">mp_obj_list_append</span>(<span class="pl-s1">outputs</span>, <span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">      }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">outputs</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">  } <span class="pl-k">else</span> {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-mlops-c-LC32" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Return the scalar input as a list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-mlops-c-LC33" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-c1">1</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-mlops-c-LC34" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-mlops-c-LC35" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-mlops-c-LC36" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-mlops-c-LC37" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/dbcf7f02d924f780477fac2a196eabbe/raw/50e77f51c4b8129aa23199e94558543488387900/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/dbcf7f02d924f780477fac2a196eabbe#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Input Normalization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120515\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>normInput</span>(<span class=pl-s1>matrix</span>, <span class=pl-s1>multiplier</span>, <span class=pl-s1>adder</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>element</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>matrix</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>if</span> <span class=pl-en>isinstance</span>(<span class=pl-s1>element</span>, (<span class=pl-s1>list</span>, <span class=pl-s1>array</span>.<span class=pl-s1>array</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c># If the current element is a list, recursively call the function on this element</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-en>normInput</span>(<span class=pl-s1>element</span>, <span class=pl-s1>multiplier</span>, <span class=pl-s1>adder</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>else</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c># If the current element is not a list, multiply it by the multiplier and add the adder</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>matrix</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> (<span class=pl-s1>element</span> <span class=pl-c1>+</span> <span class=pl-s1>adder</span>) <span class=pl-c1>*</span> <span class=pl-s1>multiplier</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>matrix</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/f5f5ae859b5608edee3489364dc0f80d/raw/8a9ab83dd80e9dc2ff53f44e5bc4cdaf3d8471ce/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/f5f5ae859b5608edee3489364dc0f80d#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120515" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">normInput</span>(<span class="pl-s1">matrix</span>, <span class="pl-s1">multiplier</span>, <span class="pl-s1">adder</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">element</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">matrix</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">if</span> <span class="pl-en">isinstance</span>(<span class="pl-s1">element</span>, (<span class="pl-s1">list</span>, <span class="pl-s1">array</span>.<span class="pl-s1">array</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">            <span class="pl-c"># If the current element is a list, recursively call the function on this element</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">            <span class="pl-en">normInput</span>(<span class="pl-s1">element</span>, <span class="pl-s1">multiplier</span>, <span class="pl-s1">adder</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">else</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">            <span class="pl-c"># If the current element is not a list, multiply it by the multiplier and add the adder</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">matrix</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> (<span class="pl-s1">element</span> <span class="pl-c1">+</span> <span class="pl-s1">adder</span>) <span class="pl-c1">*</span> <span class="pl-s1">multiplier</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">matrix</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/f5f5ae859b5608edee3489364dc0f80d/raw/8a9ab83dd80e9dc2ff53f44e5bc4cdaf3d8471ce/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/f5f5ae859b5608edee3489364dc0f80d#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Input Normalization with C Optimization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120527\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>normInput</span>(<span class=pl-s1>matrix</span>, <span class=pl-s1>multiplier</span>, <span class=pl-s1>adder</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>norm_input</span>(<span class=pl-s1>multiplier</span>, <span class=pl-s1>adder</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/26d2584f48279c8aad0038e79a27d299/raw/b737dd70ca39bae1051109cfb04e71c6c5ed9d65/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/26d2584f48279c8aad0038e79a27d299#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120527" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">normInput</span>(<span class="pl-s1">matrix</span>, <span class="pl-s1">multiplier</span>, <span class="pl-s1">adder</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">norm_input</span>(<span class="pl-s1">multiplier</span>, <span class="pl-s1">adder</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/26d2584f48279c8aad0038e79a27d299/raw/b737dd70ca39bae1051109cfb04e71c6c5ed9d65/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/26d2584f48279c8aad0038e79a27d299#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120541\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>norm_input</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>input</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>multiplier</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>adder</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-c>// Check if input is a list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  <span class=pl-k>if</span> (<span class=pl-en>mp_obj_is_type</span>(<span class=pl-s1>input</span>, <span class=pl-c1>&amp;amp;</span><span class=pl-s1>mp_type_list</span>)) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// Create a new list to hold normalized values</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>outputs</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-c1>0</span>, <span class=pl-c1>NULL</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert input list to pointer and get length</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>input_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>unsigned <span class=pl-smi>int</span></span> <span class=pl-s1>list_len</span> <span class=pl-c1>=</span> <span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>list_len</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// relu each item in input list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>normalized</span> <span class=pl-c1>=</span> <span class=pl-en>norm_input</span>(<span class=pl-s1>input_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>], <span class=pl-s1>multiplier</span>, <span class=pl-s1>adder</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-c>// append to new list</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t  <span class=pl-en>mp_obj_list_append</span>(<span class=pl-s1>outputs</span>, <span class=pl-s1>normalized</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>outputs</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  } <span class=pl-k>else</span> {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>// relu the scalar input </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>float</span> <span class=pl-s1>input_f</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>input</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>multiplier_f</span> <span class=pl-c1>=</span>  <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>multiplier</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>adder_f</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>adder</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-en>mp_obj_new_float</span>((<span class=pl-s1>input_f</span><span class=pl-c1>+</span><span class=pl-s1>adder_f</span>)<span class=pl-c1>*</span><span class=pl-s1>multiplier_f</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>  }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/082d457b7a7e5abe8b0958ccd434ecd6/raw/500ad34854de486b720b3443e681dcbcbfd8963d/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/082d457b7a7e5abe8b0958ccd434ecd6#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120541" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">norm_input</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">input</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">multiplier</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">adder</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">  <span class="pl-c">// Check if input is a list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">  <span class="pl-k">if</span> (<span class="pl-en">mp_obj_is_type</span>(<span class="pl-s1">input</span>, <span class="pl-c1">&amp;</span><span class="pl-s1">mp_type_list</span>)) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// Create a new list to hold normalized values</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">outputs</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-c1">0</span>, <span class="pl-c1">NULL</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert input list to pointer and get length</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">input_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">unsigned <span class="pl-smi">int</span></span> <span class="pl-s1">list_len</span> <span class="pl-c1">=</span> <span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">list_len</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// relu each item in input list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">      <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">normalized</span> <span class="pl-c1">=</span> <span class="pl-en">norm_input</span>(<span class="pl-s1">input_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>], <span class="pl-s1">multiplier</span>, <span class="pl-s1">adder</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-c">// append to new list</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">&#9;  <span class="pl-en">mp_obj_list_append</span>(<span class="pl-s1">outputs</span>, <span class="pl-s1">normalized</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">    }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">outputs</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">  } <span class="pl-k">else</span> {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">// relu the scalar input </span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">float</span> <span class="pl-s1">input_f</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">input</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">multiplier_f</span> <span class="pl-c1">=</span>  <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">multiplier</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">adder_f</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">adder</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-en">mp_obj_new_float</span>((<span class="pl-s1">input_f</span><span class="pl-c1">+</span><span class="pl-s1">adder_f</span>)<span class="pl-c1">*</span><span class="pl-s1">multiplier_f</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">  }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/082d457b7a7e5abe8b0958ccd434ecd6/raw/500ad34854de486b720b3443e681dcbcbfd8963d/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/082d457b7a7e5abe8b0958ccd434ecd6#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Conv2D Layer</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120117\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>convLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>in_channels</span>, <span class=pl-s1>out_channels</span>, <span class=pl-s1>kernel_size</span>: <span class=pl-s1>tuple</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span> <span class=pl-c1>=</span> [[<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>in_channels</span>)] <span class=pl-k>for</span> <span class=pl-s1>_2</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                        <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> [<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>stride</span> <span class=pl-c1>=</span> <span class=pl-s1>stride</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernel_size</span> <span class=pl-c1>=</span> <span class=pl-s1>kernel_size</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>conv_func</span> <span class=pl-c1>=</span> <span class=pl-s1>convolution2D</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>output_data</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>out_channel</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>channel_output</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>for</span> <span class=pl-s1>in_channel</span>, <span class=pl-s1>image</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>channel_output</span>.<span class=pl-en>append</span>(<span class=pl-en>conv_func</span>(<span class=pl-s1>image</span>, <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>[<span class=pl-s1>out_channel</span>][<span class=pl-s1>in_channel</span>],<span class=pl-s1>self</span>.<span class=pl-s1>stride</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### Matrix addition operation</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### sum up all the different outputs for each channel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>summed_channel_output</span> <span class=pl-c1>=</span> <span class=pl-en>sumMatrices</span>(<span class=pl-s1>channel_output</span>) </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-model-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>### Add the bias for each channel to each element </span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-model-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>### in the output matrix for that channel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-model-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>biased_channel_output</span> <span class=pl-c1>=</span> <span class=pl-en>addBias</span>(<span class=pl-s1>summed_channel_output</span>, <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>out_channel</span>]) </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-model-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>output_data</span>.<span class=pl-en>append</span>(<span class=pl-s1>biased_channel_output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-model-py-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>output_data</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-model-py-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>      </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-model-py-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>convolution2D</span>(<span class=pl-s1>image</span>, <span class=pl-s1>kernel</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-model-py-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### Convolve single 2D matrix with kernel using stride</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-model-py-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>### returns a single 2D matrix</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-model-py-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-model-py-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Get dimensions of the input matrix (image) and the kernel</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-model-py-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>image_height</span>, <span class=pl-s1>image_width</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>image</span>)), <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>image</span>[<span class=pl-c1>0</span>]))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-model-py-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>kernel_height</span>, <span class=pl-s1>kernel_width</span> <span class=pl-c1>=</span> <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>kernel</span>)), <span class=pl-en>int</span>(<span class=pl-en>len</span>(<span class=pl-s1>kernel</span>[<span class=pl-c1>0</span>]))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-model-py-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-model-py-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Calculate dimensions of the output image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-model-py-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output_height</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_height</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_height</span>) <span class=pl-c1>//</span> <span class=pl-s1>stride</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-model-py-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output_width</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_width</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_width</span>) <span class=pl-c1>//</span> <span class=pl-s1>stride</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-model-py-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-model-py-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Initialize output image with zeros</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-model-py-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-s1>output</span> <span class=pl-c1>=</span> [[<span class=pl-c1>0</span>]<span class=pl-c1>*</span><span class=pl-s1>output_width</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>output_height</span>)]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L38\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-model-py-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L39\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-model-py-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-c>### Iterate over the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L40\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-model-py-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>for</span> <span class=pl-s1>i</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-c1>0</span>, <span class=pl-s1>image_height</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L41\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-model-py-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-c>### optimization</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L42\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-model-py-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>output_y</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span><span class=pl-c1>//</span><span class=pl-s1>stride</span> </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L43\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-model-py-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>j</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-c1>0</span>, <span class=pl-s1>image_width</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L44\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-model-py-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t        <span class=pl-c>### optimization</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L45\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-model-py-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>output_x</span> <span class=pl-c1>=</span> <span class=pl-s1>j</span><span class=pl-c1>//</span><span class=pl-s1>stride</span> </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L46\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-model-py-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-c>### Check if the kernel can fit in the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L47\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-model-py-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>if</span> <span class=pl-s1>i</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_height</span> <span class=pl-c1>&amp;lt;=</span> <span class=pl-s1>image_height</span> <span class=pl-c1>and</span> <span class=pl-s1>j</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_width</span> <span class=pl-c1>&amp;lt;=</span> <span class=pl-s1>image_width</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L48\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-model-py-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-c>### Apply the kernel to the image</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L49\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-model-py-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-k>for</span> <span class=pl-s1>m</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>kernel_height</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L50\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-model-py-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-s1>i_plus_m</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span><span class=pl-c1>+</span><span class=pl-s1>m</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L51\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-model-py-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-k>for</span> <span class=pl-s1>n</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>kernel_width</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L52\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-model-py-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                        <span class=pl-s1>output</span>[<span class=pl-s1>output_y</span>][<span class=pl-s1>output_x</span>] <span class=pl-c1>+=</span> <span class=pl-s1>image</span>[<span class=pl-s1>i_plus_m</span>][<span class=pl-s1>j</span><span class=pl-c1>+</span><span class=pl-s1>n</span>] <span class=pl-c1>*</span> <span class=pl-s1>kernel</span>[<span class=pl-s1>m</span>][<span class=pl-s1>n</span>]</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L53\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-model-py-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>output</span></td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc/raw/449f39d8c83143cecd64ebc51277a6fe530165af/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120117" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">convLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">in_channels</span>, <span class="pl-s1">out_channels</span>, <span class="pl-s1">kernel_size</span>: <span class="pl-s1">tuple</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span> <span class="pl-c1">=</span> [[<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">in_channels</span>)] <span class="pl-k">for</span> <span class="pl-s1">_2</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">                        <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> [<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">stride</span> <span class="pl-c1">=</span> <span class="pl-s1">stride</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernel_size</span> <span class="pl-c1">=</span> <span class="pl-s1">kernel_size</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">conv_func</span> <span class="pl-c1">=</span> <span class="pl-s1">convolution2D</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">output_data</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">out_channel</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">channel_output</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">for</span> <span class="pl-s1">in_channel</span>, <span class="pl-s1">image</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">channel_output</span>.<span class="pl-en">append</span>(<span class="pl-en">conv_func</span>(<span class="pl-s1">image</span>, <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>[<span class="pl-s1">out_channel</span>][<span class="pl-s1">in_channel</span>],<span class="pl-s1">self</span>.<span class="pl-s1">stride</span>))</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### Matrix addition operation</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model-py-LC16" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### sum up all the different outputs for each channel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model-py-LC17" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">summed_channel_output</span> <span class="pl-c1">=</span> <span class="pl-en">sumMatrices</span>(<span class="pl-s1">channel_output</span>) </td>
        </tr>
        <tr>
          <td id="file-model-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-model-py-LC18" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">### Add the bias for each channel to each element </span></td>
        </tr>
        <tr>
          <td id="file-model-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-model-py-LC19" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">### in the output matrix for that channel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-model-py-LC20" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">biased_channel_output</span> <span class="pl-c1">=</span> <span class="pl-en">addBias</span>(<span class="pl-s1">summed_channel_output</span>, <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">out_channel</span>]) </td>
        </tr>
        <tr>
          <td id="file-model-py-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-model-py-LC21" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">output_data</span>.<span class="pl-en">append</span>(<span class="pl-s1">biased_channel_output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-model-py-LC22" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">output_data</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-model-py-LC23" class="blob-code blob-code-inner js-file-line">      </td>
        </tr>
        <tr>
          <td id="file-model-py-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-model-py-LC24" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">convolution2D</span>(<span class="pl-s1">image</span>, <span class="pl-s1">kernel</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-model-py-LC25" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### Convolve single 2D matrix with kernel using stride</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-model-py-LC26" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">### returns a single 2D matrix</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-model-py-LC27" class="blob-code blob-code-inner js-file-line">    </td>
        </tr>
        <tr>
          <td id="file-model-py-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-model-py-LC28" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Get dimensions of the input matrix (image) and the kernel</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-model-py-LC29" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">image_height</span>, <span class="pl-s1">image_width</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">image</span>)), <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">image</span>[<span class="pl-c1">0</span>]))</td>
        </tr>
        <tr>
          <td id="file-model-py-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-model-py-LC30" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">kernel_height</span>, <span class="pl-s1">kernel_width</span> <span class="pl-c1">=</span> <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">kernel</span>)), <span class="pl-en">int</span>(<span class="pl-en">len</span>(<span class="pl-s1">kernel</span>[<span class="pl-c1">0</span>]))</td>
        </tr>
        <tr>
          <td id="file-model-py-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-model-py-LC31" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-model-py-LC32" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Calculate dimensions of the output image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-model-py-LC33" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output_height</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_height</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_height</span>) <span class="pl-c1">//</span> <span class="pl-s1">stride</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-model-py-LC34" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output_width</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_width</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_width</span>) <span class="pl-c1">//</span> <span class="pl-s1">stride</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-model-py-LC35" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-model-py-LC36" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Initialize output image with zeros</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-model-py-LC37" class="blob-code blob-code-inner js-file-line">    <span class="pl-s1">output</span> <span class="pl-c1">=</span> [[<span class="pl-c1">0</span>]<span class="pl-c1">*</span><span class="pl-s1">output_width</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">output_height</span>)]</td>
        </tr>
        <tr>
          <td id="file-model-py-L38" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-model-py-LC38" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L39" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-model-py-LC39" class="blob-code blob-code-inner js-file-line">    <span class="pl-c">### Iterate over the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L40" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-model-py-LC40" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">for</span> <span class="pl-s1">i</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">0</span>, <span class="pl-s1">image_height</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L41" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-model-py-LC41" class="blob-code blob-code-inner js-file-line">        <span class="pl-c">### optimization</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L42" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-model-py-LC42" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">output_y</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span><span class="pl-c1">//</span><span class="pl-s1">stride</span> </td>
        </tr>
        <tr>
          <td id="file-model-py-L43" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-model-py-LC43" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">j</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-c1">0</span>, <span class="pl-s1">image_width</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L44" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-model-py-LC44" class="blob-code blob-code-inner js-file-line">&#9;        <span class="pl-c">### optimization</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L45" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-model-py-LC45" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">output_x</span> <span class="pl-c1">=</span> <span class="pl-s1">j</span><span class="pl-c1">//</span><span class="pl-s1">stride</span> </td>
        </tr>
        <tr>
          <td id="file-model-py-L46" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-model-py-LC46" class="blob-code blob-code-inner js-file-line">            <span class="pl-c">### Check if the kernel can fit in the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L47" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-model-py-LC47" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">if</span> <span class="pl-s1">i</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_height</span> <span class="pl-c1">&lt;=</span> <span class="pl-s1">image_height</span> <span class="pl-c1">and</span> <span class="pl-s1">j</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_width</span> <span class="pl-c1">&lt;=</span> <span class="pl-s1">image_width</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L48" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-model-py-LC48" class="blob-code blob-code-inner js-file-line">                <span class="pl-c">### Apply the kernel to the image</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L49" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-model-py-LC49" class="blob-code blob-code-inner js-file-line">                <span class="pl-k">for</span> <span class="pl-s1">m</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">kernel_height</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L50" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-model-py-LC50" class="blob-code blob-code-inner js-file-line">                    <span class="pl-s1">i_plus_m</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span><span class="pl-c1">+</span><span class="pl-s1">m</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L51" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-model-py-LC51" class="blob-code blob-code-inner js-file-line">                    <span class="pl-k">for</span> <span class="pl-s1">n</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">kernel_width</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L52" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-model-py-LC52" class="blob-code blob-code-inner js-file-line">                        <span class="pl-s1">output</span>[<span class="pl-s1">output_y</span>][<span class="pl-s1">output_x</span>] <span class="pl-c1">+=</span> <span class="pl-s1">image</span>[<span class="pl-s1">i_plus_m</span>][<span class="pl-s1">j</span><span class="pl-c1">+</span><span class="pl-s1">n</span>] <span class="pl-c1">*</span> <span class="pl-s1">kernel</span>[<span class="pl-s1">m</span>][<span class="pl-s1">n</span>]</td>
        </tr>
        <tr>
          <td id="file-model-py-L53" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-model-py-LC53" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">output</span></td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc/raw/449f39d8c83143cecd64ebc51277a6fe530165af/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/e6071d55d8c1907348e29705144d0bbc#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><h2>Conv2D Layer with C optimization</h2><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120609\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-model-py\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-python  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;Python\&quot; data-tagsearch-path=\&quot;model.py\&quot;>\n        <tr>\n          <td id=\&quot;file-model-py-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-model-py-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>class</span> <span class=pl-s1>convLayer</span>(<span class=pl-v>Module</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-model-py-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__init__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>in_channels</span>, <span class=pl-s1>out_channels</span>, <span class=pl-s1>kernel_size</span>: <span class=pl-s1>tuple</span>, <span class=pl-s1>stride</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-model-py-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span> <span class=pl-c1>=</span> [[<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>in_channels</span>)] <span class=pl-k>for</span> <span class=pl-s1>_2</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-model-py-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                        <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]<span class=pl-c># Start with no kernels</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-model-py-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>bias</span> <span class=pl-c1>=</span> [<span class=pl-c1>None</span> <span class=pl-k>for</span> <span class=pl-s1>_</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-s1>out_channels</span>)]<span class=pl-c># Start with no kernels</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-model-py-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>stride</span> <span class=pl-c1>=</span> <span class=pl-s1>stride</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-model-py-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>self</span>.<span class=pl-s1>kernel_size</span> <span class=pl-c1>=</span> <span class=pl-s1>kernel_size</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-model-py-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-model-py-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>__call__</span>(<span class=pl-s1>self</span>, <span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-model-py-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>conv_func</span> <span class=pl-c1>=</span> <span class=pl-s1>mlops</span>.<span class=pl-s1>conv2d</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-model-py-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-s1>output_data</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-model-py-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>out_channel</span> <span class=pl-c1>in</span> <span class=pl-en>range</span>(<span class=pl-en>len</span>(<span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>)):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-model-py-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>channel_output</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-model-py-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>for</span> <span class=pl-s1>in_channel</span>, <span class=pl-s1>image</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>images</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-model-py-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>channel_output</span>.<span class=pl-en>append</span>(<span class=pl-en>conv_func</span>(<span class=pl-s1>image</span>, <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>[<span class=pl-s1>out_channel</span>][<span class=pl-s1>in_channel</span>],<span class=pl-s1>self</span>.<span class=pl-s1>stride</span>))</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-model-py-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>biased_channel_output</span> <span class=pl-c1>=</span> <span class=pl-en>sumMatricesAddBias</span>(<span class=pl-s1>channel_output</span>, <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>out_channel</span>])</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-model-py-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>output_data</span>.<span class=pl-en>append</span>(<span class=pl-s1>biased_channel_output</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-model-py-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>return</span> <span class=pl-s1>output_data</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-model-py-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>def</span> <span class=pl-en>load_state_dict</span>(<span class=pl-s1>self</span>, <span class=pl-s1>weights</span>, <span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-model-py-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>in_channels</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>weights</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-model-py-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-k>for</span> <span class=pl-s1>j</span>, <span class=pl-s1>kernels</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>in_channels</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-model-py-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>kernel_data</span> <span class=pl-c1>=</span> []</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-model-py-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-k>for</span> <span class=pl-s1>row</span> <span class=pl-c1>in</span> <span class=pl-s1>kernels</span>:</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-model-py-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                    <span class=pl-s1>kernel_data</span>.<span class=pl-en>append</span>(<span class=pl-s1>row</span>)</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-model-py-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>                <span class=pl-s1>self</span>.<span class=pl-s1>kernels</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-s1>kernel_data</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-model-py-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>        <span class=pl-k>for</span> <span class=pl-s1>i</span>, <span class=pl-s1>b</span> <span class=pl-c1>in</span> <span class=pl-en>enumerate</span>(<span class=pl-s1>bias</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-model-py-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>            <span class=pl-s1>self</span>.<span class=pl-s1>bias</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-s1>b</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-model-py-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-model-py-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-en>@<span class=pl-s1>micropython</span>.<span class=pl-s1>native</span></span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-model-py-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-k>def</span> <span class=pl-en>sumMatricesAddBias</span>(<span class=pl-s1>matrices</span>, <span class=pl-s1>bias</span><span class=pl-c1>=</span><span class=pl-c1>0.0</span>):</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-model-py-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-model-py-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-k>return</span> <span class=pl-s1>mlops</span>.<span class=pl-en>sum_matrices</span>(<span class=pl-s1>matrices</span>, <span class=pl-s1>bias</span>)</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/d5bb18350012efbdb44e5224bad87a27/raw/0bc8db1bd423fc367f72952ac4a7abdbe4e2d71a/model.py\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/d5bb18350012efbdb44e5224bad87a27#file-model-py\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          model.py\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120609" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-model-py" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-python  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="Python" data-tagsearch-path="model.py">
        <tbody><tr>
          <td id="file-model-py-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-model-py-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-k">class</span> <span class="pl-s1">convLayer</span>(<span class="pl-v">Module</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-model-py-LC2" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__init__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">in_channels</span>, <span class="pl-s1">out_channels</span>, <span class="pl-s1">kernel_size</span>: <span class="pl-s1">tuple</span>, <span class="pl-s1">stride</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-model-py-LC3" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span> <span class="pl-c1">=</span> [[<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">in_channels</span>)] <span class="pl-k">for</span> <span class="pl-s1">_2</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-model-py-LC4" class="blob-code blob-code-inner js-file-line">                        <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]<span class="pl-c"># Start with no kernels</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-model-py-LC5" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">bias</span> <span class="pl-c1">=</span> [<span class="pl-c1">None</span> <span class="pl-k">for</span> <span class="pl-s1">_</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-s1">out_channels</span>)]<span class="pl-c"># Start with no kernels</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-model-py-LC6" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">stride</span> <span class="pl-c1">=</span> <span class="pl-s1">stride</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-model-py-LC7" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">self</span>.<span class="pl-s1">kernel_size</span> <span class="pl-c1">=</span> <span class="pl-s1">kernel_size</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-model-py-LC8" class="blob-code blob-code-inner js-file-line">    <span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-model-py-LC9" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">__call__</span>(<span class="pl-s1">self</span>, <span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-model-py-LC10" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">conv_func</span> <span class="pl-c1">=</span> <span class="pl-s1">mlops</span>.<span class="pl-s1">conv2d</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-model-py-LC11" class="blob-code blob-code-inner js-file-line">        <span class="pl-s1">output_data</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-model-py-LC12" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">out_channel</span> <span class="pl-c1">in</span> <span class="pl-en">range</span>(<span class="pl-en">len</span>(<span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>)):</td>
        </tr>
        <tr>
          <td id="file-model-py-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-model-py-LC13" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">channel_output</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-model-py-LC14" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">for</span> <span class="pl-s1">in_channel</span>, <span class="pl-s1">image</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">images</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-model-py-LC15" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">channel_output</span>.<span class="pl-en">append</span>(<span class="pl-en">conv_func</span>(<span class="pl-s1">image</span>, <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>[<span class="pl-s1">out_channel</span>][<span class="pl-s1">in_channel</span>],<span class="pl-s1">self</span>.<span class="pl-s1">stride</span>))</td>
        </tr>
        <tr>
          <td id="file-model-py-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-model-py-LC16" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">biased_channel_output</span> <span class="pl-c1">=</span> <span class="pl-en">sumMatricesAddBias</span>(<span class="pl-s1">channel_output</span>, <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">out_channel</span>])</td>
        </tr>
        <tr>
          <td id="file-model-py-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-model-py-LC17" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">output_data</span>.<span class="pl-en">append</span>(<span class="pl-s1">biased_channel_output</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-model-py-LC18" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">return</span> <span class="pl-s1">output_data</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-model-py-LC19" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">def</span> <span class="pl-en">load_state_dict</span>(<span class="pl-s1">self</span>, <span class="pl-s1">weights</span>, <span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-model-py-LC20" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">in_channels</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">weights</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-model-py-LC21" class="blob-code blob-code-inner js-file-line">            <span class="pl-k">for</span> <span class="pl-s1">j</span>, <span class="pl-s1">kernels</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">in_channels</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-model-py-LC22" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">kernel_data</span> <span class="pl-c1">=</span> []</td>
        </tr>
        <tr>
          <td id="file-model-py-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-model-py-LC23" class="blob-code blob-code-inner js-file-line">                <span class="pl-k">for</span> <span class="pl-s1">row</span> <span class="pl-c1">in</span> <span class="pl-s1">kernels</span>:</td>
        </tr>
        <tr>
          <td id="file-model-py-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-model-py-LC24" class="blob-code blob-code-inner js-file-line">                    <span class="pl-s1">kernel_data</span>.<span class="pl-en">append</span>(<span class="pl-s1">row</span>)</td>
        </tr>
        <tr>
          <td id="file-model-py-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-model-py-LC25" class="blob-code blob-code-inner js-file-line">                <span class="pl-s1">self</span>.<span class="pl-s1">kernels</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-s1">kernel_data</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-model-py-LC26" class="blob-code blob-code-inner js-file-line">        <span class="pl-k">for</span> <span class="pl-s1">i</span>, <span class="pl-s1">b</span> <span class="pl-c1">in</span> <span class="pl-en">enumerate</span>(<span class="pl-s1">bias</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-model-py-LC27" class="blob-code blob-code-inner js-file-line">            <span class="pl-s1">self</span>.<span class="pl-s1">bias</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-s1">b</span></td>
        </tr>
        <tr>
          <td id="file-model-py-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-model-py-LC28" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-model-py-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-model-py-LC29" class="blob-code blob-code-inner js-file-line"><span class="pl-en">@<span class="pl-s1">micropython</span>.<span class="pl-s1">native</span></span></td>
        </tr>
        <tr>
          <td id="file-model-py-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-model-py-LC30" class="blob-code blob-code-inner js-file-line"><span class="pl-k">def</span> <span class="pl-en">sumMatricesAddBias</span>(<span class="pl-s1">matrices</span>, <span class="pl-s1">bias</span><span class="pl-c1">=</span><span class="pl-c1">0.0</span>):</td>
        </tr>
        <tr>
          <td id="file-model-py-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-model-py-LC31" class="blob-code blob-code-inner js-file-line">    <span class="pl-k">return</span> <span class="pl-s1">mlops</span>.<span class="pl-en">sum_matrices</span>(<span class="pl-s1">matrices</span>, <span class="pl-s1">bias</span>)</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/d5bb18350012efbdb44e5224bad87a27/raw/0bc8db1bd423fc367f72952ac4a7abdbe4e2d71a/model.py" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/d5bb18350012efbdb44e5224bad87a27#file-model-py" class="Link--inTextBlock">
          model.py
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="github-gist" data-attrs="{&quot;innerHTML&quot;:&quot;<div id=\&quot;gist126120626\&quot; class=\&quot;gist\&quot;>\n    <div class=\&quot;gist-file\&quot; translate=\&quot;no\&quot;>\n      <div class=\&quot;gist-data\&quot;>\n        <div class=\&quot;js-gist-file-update-container js-task-list-container file-box\&quot;>\n  <div id=\&quot;file-mlops-c\&quot; class=\&quot;file my-2\&quot;>\n    \n    <div itemprop=\&quot;text\&quot; class=\&quot;Box-body p-0 blob-wrapper data type-c  \&quot;>\n\n        \n<div class=\&quot;js-check-bidi js-blob-code-container blob-code-content\&quot;>\n\n  <template class=\&quot;js-file-alert-template\&quot;>\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash flash-warn flash-full d-flex flex-items-center\&quot;>\n  <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n    <span>\n      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.co/hiddenchars\&quot; target=\&quot;_blank\&quot;>Learn more about bidirectional Unicode characters</a>\n    </span>\n\n\n  <div data-view-component=\&quot;true\&quot; class=\&quot;flash-action\&quot;>        <a href=\&quot;{{ revealButtonHref }}\&quot; data-view-component=\&quot;true\&quot; class=\&quot;btn-sm btn\&quot;>    Show hidden characters\n</a>\n</div>\n</div></template>\n<template class=\&quot;js-line-alert-template\&quot;>\n  <span aria-label=\&quot;This line has hidden Unicode characters\&quot; data-view-component=\&quot;true\&quot; class=\&quot;line-alert tooltipped tooltipped-e\&quot;>\n    <svg aria-hidden=\&quot;true\&quot; height=\&quot;16\&quot; viewBox=\&quot;0 0 16 16\&quot; version=\&quot;1.1\&quot; width=\&quot;16\&quot; data-view-component=\&quot;true\&quot; class=\&quot;octicon octicon-alert\&quot;>\n    <path d=\&quot;M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\&quot;></path>\n</svg>\n</span></template>\n\n  <table data-hpc class=\&quot;highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file\&quot; data-tab-size=\&quot;8\&quot; data-paste-markdown-skip data-tagsearch-lang=\&quot;C\&quot; data-tagsearch-path=\&quot;mlops.c\&quot;>\n        <tr>\n          <td id=\&quot;file-mlops-c-L1\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;1\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC1\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>conv2d</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>image</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>kernel</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>stride</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L2\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;2\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC2\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert from mpy lists to pointers</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L3\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;3\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC3\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>image_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>image</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L4\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;4\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC4\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>image_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>image_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-c1>0</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L5\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;5\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC5\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>kernel_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>kernel</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L6\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;6\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC6\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t <span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>kernel_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>kernel_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-c1>0</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L7\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;7\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC7\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert from mpy object to c</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L8\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;8\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC8\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>int</span> <span class=pl-s1>stride_c</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_int</span>(<span class=pl-s1>stride</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L9\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;9\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC9\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L10\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;10\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC10\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L11\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;11\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC11\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>size_t</span> <span class=pl-s1>image_height</span> <span class=pl-c1>=</span> <span class=pl-s1>image_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L12\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;12\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC12\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>size_t</span> <span class=pl-s1>image_width</span> <span class=pl-c1>=</span> <span class=pl-s1>image_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L13\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;13\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC13\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>size_t</span> <span class=pl-s1>kernel_height</span> <span class=pl-c1>=</span> <span class=pl-s1>kernel_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L14\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;14\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC14\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>size_t</span> <span class=pl-s1>kernel_width</span> <span class=pl-c1>=</span> <span class=pl-s1>kernel_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L15\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;15\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC15\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L16\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;16\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC16\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L17\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;17\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC17\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>int</span> <span class=pl-s1>output_height</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_height</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_height</span>) / <span class=pl-s1>stride_c</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L18\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;18\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC18\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>const</span> <span class=pl-smi>int</span> <span class=pl-s1>output_width</span> <span class=pl-c1>=</span> (<span class=pl-s1>image_width</span> <span class=pl-c1>-</span> <span class=pl-s1>kernel_width</span>) / <span class=pl-s1>stride_c</span> <span class=pl-c1>+</span> <span class=pl-c1>1</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L19\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;19\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC19\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L20\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;20\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC20\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Create output array of zeroes</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L21\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;21\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC21\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>output</span>[<span class=pl-s1>output_height</span>][<span class=pl-s1>output_width</span>];</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L22\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;22\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC22\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>output_width</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L23\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;23\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC23\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t  <span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>output_height</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L24\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;24\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC24\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>output</span>[<span class=pl-s1>j</span>][<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-c1>0.0</span>; </td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L25\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;25\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC25\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t  }</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L26\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;26\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC26\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L27\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;27\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC27\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convolve</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L28\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;28\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC28\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>output_y</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L29\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;29\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC29\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>output_x</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L30\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;30\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC30\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>i_plus_m</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L31\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;31\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC31\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>image_height</span>; <span class=pl-s1>i</span><span class=pl-c1>+=</span> <span class=pl-s1>stride_c</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L32\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;32\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC32\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>output_y</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span>/<span class=pl-s1>stride_c</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L33\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;33\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC33\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>image_width</span>; <span class=pl-s1>j</span><span class=pl-c1>+=</span> <span class=pl-s1>stride_c</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L34\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;34\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC34\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>output_x</span> <span class=pl-c1>=</span> <span class=pl-s1>j</span>/<span class=pl-s1>stride_c</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L35\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;35\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC35\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>if</span> (<span class=pl-s1>i</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_height</span> &amp;lt;= <span class=pl-s1>image_height</span> <span class=pl-c1>&amp;amp;&amp;amp;</span> <span class=pl-s1>j</span> <span class=pl-c1>+</span> <span class=pl-s1>kernel_width</span> &amp;lt;= <span class=pl-s1>image_width</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L36\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;36\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC36\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>// code to execute if condition is true</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L37\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;37\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC37\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>m</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>m</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>kernel_height</span>; <span class=pl-s1>m</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L38\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;38\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC38\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t<span class=pl-s1>i_plus_m</span> <span class=pl-c1>=</span> <span class=pl-s1>i</span><span class=pl-c1>+</span><span class=pl-s1>m</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L39\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;39\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC39\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t<span class=pl-s1>image_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>image_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i_plus_m</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L40\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;40\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC40\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t<span class=pl-s1>kernel_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>kernel_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>m</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L41\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;41\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC41\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>n</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>n</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>kernel_width</span>; <span class=pl-s1>n</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L42\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;42\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC42\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t\t<span class=pl-s1>output</span>[<span class=pl-s1>output_y</span>][<span class=pl-s1>output_x</span>] <span class=pl-c1>+=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>image_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>j</span><span class=pl-c1>+</span><span class=pl-s1>n</span>]) <span class=pl-c1>*</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>kernel_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>n</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L43\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;43\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC43\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L44\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;44\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC44\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L45\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;45\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC45\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t}\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L46\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;46\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC46\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L47\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;47\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC47\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L48\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;48\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC48\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L49\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;49\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC49\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L50\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;50\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC50\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L51\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;51\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC51\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert result calculated above to mpy compatible object</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L52\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;52\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC52\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>temp_row</span>[<span class=pl-s1>output_width</span>];<span class=pl-c>//store rows in this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L53\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;53\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC53\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>output_height</span>];<span class=pl-c>//store lists of rows in this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L54\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;54\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC54\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>output_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L55\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;55\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC55\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>output_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L56\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;56\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC56\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>// first convert all values to float</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L57\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;57\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC57\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>temp_row</span>[<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_float</span>(<span class=pl-s1>output</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L58\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;58\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC58\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L59\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;59\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC59\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-s1>output_width</span>, <span class=pl-s1>temp_row</span>);<span class=pl-c>//convert row to mp list and store into array</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L60\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;60\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC60\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L61\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;61\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC61\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L62\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;62\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC62\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L63\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;63\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC63\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-s1>output_height</span>, <span class=pl-s1>output_converted_to_mp</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L64\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;64\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC64\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L65\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;65\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC65\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L66\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;66\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC66\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L67\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;67\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC67\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;><span class=pl-smi>STATIC</span> <span class=pl-s1>mp_obj_t</span> <span class=pl-en>sum_matrices</span>(<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>matrices</span>, <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>bias</span>) {</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L68\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;68\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC68\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert from mpy lists to pointers and mpy float to c float</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L69\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;69\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC69\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>bias_f</span> <span class=pl-c1>=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>bias</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L70\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;70\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC70\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>matrices_c</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>matrices</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L71\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;71\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC71\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>first_matrix</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>matrices_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-c1>0</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L72\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;72\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC72\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>first_matrix_first_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>first_matrix</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-c1>0</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L73\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;73\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC73\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>num_matrices</span> <span class=pl-c1>=</span> <span class=pl-s1>matrices_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L74\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;74\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC74\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>matrix_height</span> <span class=pl-c1>=</span> <span class=pl-s1>first_matrix</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L75\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;75\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC75\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>int</span> <span class=pl-s1>matrix_width</span> <span class=pl-c1>=</span> <span class=pl-s1>first_matrix_first_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>len</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L76\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;76\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC76\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L77\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;77\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC77\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Initialize result matrix with zeroes</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L78\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;78\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC78\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>float</span> <span class=pl-s1>result</span>[<span class=pl-s1>matrix_height</span>][<span class=pl-s1>matrix_width</span>];</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L79\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;79\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC79\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L80\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;80\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC80\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span> (<span class=pl-smi>int</span> <span class=pl-s1>j</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L81\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;81\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC81\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>result</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-s1>bias_f</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L82\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;82\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC82\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L83\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;83\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC83\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L84\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;84\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC84\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L85\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;85\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC85\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>matrix</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L86\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;86\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC86\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_list_t</span> <span class=pl-c1>*</span><span class=pl-s1>matrix_row</span>;</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L87\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;87\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC87\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>n</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>n</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>num_matrices</span>; <span class=pl-s1>n</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L88\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;88\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC88\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>matrix</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>matrices_c</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>n</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L89\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;89\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC89\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L90\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;90\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC90\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>matrix_row</span> <span class=pl-c1>=</span> <span class=pl-en>MP_OBJ_TO_PTR</span>(<span class=pl-s1>matrix</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>i</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L91\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;91\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC91\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L92\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;92\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC92\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t\t<span class=pl-s1>result</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>] <span class=pl-c1>+=</span> <span class=pl-en>mp_obj_get_float</span>(<span class=pl-s1>matrix_row</span><span class=pl-c1>-&amp;gt;</span><span class=pl-c1>items</span>[<span class=pl-s1>j</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L93\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;93\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC93\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L94\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;94\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC94\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L95\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;95\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC95\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L96\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;96\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC96\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L97\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;97\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC97\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-c>// Convert result calculated above to mpy compatible object</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L98\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;98\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC98\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>    <span class=pl-smi>mp_obj_t</span> <span class=pl-s1>temp_row</span>[<span class=pl-s1>matrix_width</span>];<span class=pl-c>//store rows in this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L99\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;99\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC99\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-smi>mp_obj_t</span> <span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>matrix_height</span>];<span class=pl-c>//store lists of rows in this</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L100\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;100\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC100\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>i</span><span class=pl-c1>=</span><span class=pl-c1>0</span>; <span class=pl-s1>i</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_height</span>; <span class=pl-s1>i</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L101\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;101\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC101\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-k>for</span>(<span class=pl-smi>int</span> <span class=pl-s1>j</span> <span class=pl-c1>=</span> <span class=pl-c1>0</span>; <span class=pl-s1>j</span> <span class=pl-c1>&amp;lt;</span> <span class=pl-s1>matrix_width</span>; <span class=pl-s1>j</span><span class=pl-c1>++</span>){</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L102\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;102\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC102\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-c>// first convert all values to float</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L103\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;103\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC103\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t\t<span class=pl-s1>temp_row</span>[<span class=pl-s1>j</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_float</span>(<span class=pl-s1>result</span>[<span class=pl-s1>i</span>][<span class=pl-s1>j</span>]);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L104\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;104\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC104\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L105\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;105\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC105\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t\t<span class=pl-s1>output_converted_to_mp</span>[<span class=pl-s1>i</span>] <span class=pl-c1>=</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-s1>matrix_width</span>, <span class=pl-s1>temp_row</span>);<span class=pl-c>//convert row to mp list and store into array</span></td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L106\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;106\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC106\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t}</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L107\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;107\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC107\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L108\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;108\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC108\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\t<span class=pl-k>return</span> <span class=pl-en>mp_obj_new_list</span>(<span class=pl-s1>matrix_height</span>, <span class=pl-s1>output_converted_to_mp</span>);</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L109\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;109\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC109\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>\n</td>\n        </tr>\n        <tr>\n          <td id=\&quot;file-mlops-c-L110\&quot; class=\&quot;blob-num js-line-number js-code-nav-line-number js-blob-rnum\&quot; data-line-number=\&quot;110\&quot;></td>\n          <td id=\&quot;file-mlops-c-LC110\&quot; class=\&quot;blob-code blob-code-inner js-file-line\&quot;>}</td>\n        </tr>\n  </table>\n</div>\n\n\n    </div>\n\n  </div>\n</div>\n\n      </div>\n      <div class=\&quot;gist-meta\&quot;>\n        <a href=\&quot;https://gist.github.com/Amplify4177/f886102dbd47e9de906c4e445c66286b/raw/7c2cf1be78df8c02bb06d6adc3934ff7f520055d/mlops.c\&quot; style=\&quot;float:right\&quot; class=\&quot;Link--inTextBlock\&quot;>view raw</a>\n        <a href=\&quot;https://gist.github.com/Amplify4177/f886102dbd47e9de906c4e445c66286b#file-mlops-c\&quot; class=\&quot;Link--inTextBlock\&quot;>\n          mlops.c\n        </a>\n        hosted with &amp;#10084; by <a class=\&quot;Link--inTextBlock\&quot; href=\&quot;https://github.com\&quot;>GitHub</a>\n      </div>\n    </div>\n</div>\n&quot;,&quot;stylesheet&quot;:&quot;https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css&quot;}" data-component-name="GitgistToDOM"><link rel="stylesheet" href="https://github.githubassets.com/assets/gist-embed-232d920b3dfe.css"><div id="gist126120626" class="gist">
    <div class="gist-file">
      <div class="gist-data">
        <div class="js-gist-file-update-container js-task-list-container file-box">
  <div id="file-mlops-c" class="file my-2">
    
    <div itemprop="text" class="Box-body p-0 blob-wrapper data type-c  ">

        
<div class="js-check-bidi js-blob-code-container blob-code-content">

  
  <div data-view-component="true" class="flash flash-warn flash-full d-flex flex-items-center">
  
    

    <span>
      This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      <a class="Link--inTextBlock" href="https://github.co/hiddenchars" target="_blank">Learn more about bidirectional Unicode characters</a>
    </span>


  <div data-view-component="true" class="flash-action">        <a href="{{ revealButtonHref }}" data-view-component="true" class="btn-sm btn">    Show hidden characters
</a>
</div>
</div>

  <span data-view-component="true" class="line-alert tooltipped tooltipped-e">
    
    

</span>

  <table data-hpc="" class="highlight tab-size js-file-line-container js-code-nav-container js-tagsearch-file" data-tab-size="8" data-paste-markdown-skip="" data-tagsearch-lang="C" data-tagsearch-path="mlops.c">
        <tbody><tr>
          <td id="file-mlops-c-L1" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="1"></td>
          <td id="file-mlops-c-LC1" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">conv2d</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">image</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">kernel</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">stride</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L2" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="2"></td>
          <td id="file-mlops-c-LC2" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert from mpy lists to pointers</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L3" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="3"></td>
          <td id="file-mlops-c-LC3" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">image_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">image</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L4" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="4"></td>
          <td id="file-mlops-c-LC4" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">image_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">image_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-c1">0</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L5" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="5"></td>
          <td id="file-mlops-c-LC5" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">kernel_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">kernel</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L6" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="6"></td>
          <td id="file-mlops-c-LC6" class="blob-code blob-code-inner js-file-line">&#9; <span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">kernel_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">kernel_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-c1">0</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L7" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="7"></td>
          <td id="file-mlops-c-LC7" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert from mpy object to c</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L8" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="8"></td>
          <td id="file-mlops-c-LC8" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">int</span> <span class="pl-s1">stride_c</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_int</span>(<span class="pl-s1">stride</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L9" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="9"></td>
          <td id="file-mlops-c-LC9" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L10" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="10"></td>
          <td id="file-mlops-c-LC10" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L11" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="11"></td>
          <td id="file-mlops-c-LC11" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">size_t</span> <span class="pl-s1">image_height</span> <span class="pl-c1">=</span> <span class="pl-s1">image_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L12" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="12"></td>
          <td id="file-mlops-c-LC12" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">size_t</span> <span class="pl-s1">image_width</span> <span class="pl-c1">=</span> <span class="pl-s1">image_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L13" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="13"></td>
          <td id="file-mlops-c-LC13" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">size_t</span> <span class="pl-s1">kernel_height</span> <span class="pl-c1">=</span> <span class="pl-s1">kernel_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L14" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="14"></td>
          <td id="file-mlops-c-LC14" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">size_t</span> <span class="pl-s1">kernel_width</span> <span class="pl-c1">=</span> <span class="pl-s1">kernel_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L15" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="15"></td>
          <td id="file-mlops-c-LC15" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L16" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="16"></td>
          <td id="file-mlops-c-LC16" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L17" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="17"></td>
          <td id="file-mlops-c-LC17" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">int</span> <span class="pl-s1">output_height</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_height</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_height</span>) / <span class="pl-s1">stride_c</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L18" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="18"></td>
          <td id="file-mlops-c-LC18" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">const</span> <span class="pl-smi">int</span> <span class="pl-s1">output_width</span> <span class="pl-c1">=</span> (<span class="pl-s1">image_width</span> <span class="pl-c1">-</span> <span class="pl-s1">kernel_width</span>) / <span class="pl-s1">stride_c</span> <span class="pl-c1">+</span> <span class="pl-c1">1</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L19" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="19"></td>
          <td id="file-mlops-c-LC19" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L20" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="20"></td>
          <td id="file-mlops-c-LC20" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Create output array of zeroes</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L21" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="21"></td>
          <td id="file-mlops-c-LC21" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">output</span>[<span class="pl-s1">output_height</span>][<span class="pl-s1">output_width</span>];</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L22" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="22"></td>
          <td id="file-mlops-c-LC22" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">output_width</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L23" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="23"></td>
          <td id="file-mlops-c-LC23" class="blob-code blob-code-inner js-file-line">&#9;&#9;  <span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">output_height</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L24" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="24"></td>
          <td id="file-mlops-c-LC24" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">output</span>[<span class="pl-s1">j</span>][<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-c1">0.0</span>; </td>
        </tr>
        <tr>
          <td id="file-mlops-c-L25" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="25"></td>
          <td id="file-mlops-c-LC25" class="blob-code blob-code-inner js-file-line">&#9;&#9;  }</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L26" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="26"></td>
          <td id="file-mlops-c-LC26" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L27" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="27"></td>
          <td id="file-mlops-c-LC27" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convolve</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L28" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="28"></td>
          <td id="file-mlops-c-LC28" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">output_y</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L29" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="29"></td>
          <td id="file-mlops-c-LC29" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">output_x</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L30" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="30"></td>
          <td id="file-mlops-c-LC30" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">i_plus_m</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L31" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="31"></td>
          <td id="file-mlops-c-LC31" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">image_height</span>; <span class="pl-s1">i</span><span class="pl-c1">+=</span> <span class="pl-s1">stride_c</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L32" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="32"></td>
          <td id="file-mlops-c-LC32" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">output_y</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span>/<span class="pl-s1">stride_c</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L33" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="33"></td>
          <td id="file-mlops-c-LC33" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">image_width</span>; <span class="pl-s1">j</span><span class="pl-c1">+=</span> <span class="pl-s1">stride_c</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L34" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="34"></td>
          <td id="file-mlops-c-LC34" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">output_x</span> <span class="pl-c1">=</span> <span class="pl-s1">j</span>/<span class="pl-s1">stride_c</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L35" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="35"></td>
          <td id="file-mlops-c-LC35" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">if</span> (<span class="pl-s1">i</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_height</span> &lt;= <span class="pl-s1">image_height</span> <span class="pl-c1">&amp;&amp;</span> <span class="pl-s1">j</span> <span class="pl-c1">+</span> <span class="pl-s1">kernel_width</span> &lt;= <span class="pl-s1">image_width</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L36" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="36"></td>
          <td id="file-mlops-c-LC36" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">// code to execute if condition is true</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L37" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="37"></td>
          <td id="file-mlops-c-LC37" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">m</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">m</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">kernel_height</span>; <span class="pl-s1">m</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L38" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="38"></td>
          <td id="file-mlops-c-LC38" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;<span class="pl-s1">i_plus_m</span> <span class="pl-c1">=</span> <span class="pl-s1">i</span><span class="pl-c1">+</span><span class="pl-s1">m</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L39" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="39"></td>
          <td id="file-mlops-c-LC39" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;<span class="pl-s1">image_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">image_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i_plus_m</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L40" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="40"></td>
          <td id="file-mlops-c-LC40" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;<span class="pl-s1">kernel_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">kernel_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">m</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L41" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="41"></td>
          <td id="file-mlops-c-LC41" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">n</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">n</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">kernel_width</span>; <span class="pl-s1">n</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L42" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="42"></td>
          <td id="file-mlops-c-LC42" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;&#9;<span class="pl-s1">output</span>[<span class="pl-s1">output_y</span>][<span class="pl-s1">output_x</span>] <span class="pl-c1">+=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">image_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">j</span><span class="pl-c1">+</span><span class="pl-s1">n</span>]) <span class="pl-c1">*</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">kernel_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">n</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L43" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="43"></td>
          <td id="file-mlops-c-LC43" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L44" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="44"></td>
          <td id="file-mlops-c-LC44" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L45" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="45"></td>
          <td id="file-mlops-c-LC45" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;}&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L46" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="46"></td>
          <td id="file-mlops-c-LC46" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L47" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="47"></td>
          <td id="file-mlops-c-LC47" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L48" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="48"></td>
          <td id="file-mlops-c-LC48" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L49" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="49"></td>
          <td id="file-mlops-c-LC49" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L50" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="50"></td>
          <td id="file-mlops-c-LC50" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L51" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="51"></td>
          <td id="file-mlops-c-LC51" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert result calculated above to mpy compatible object</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L52" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="52"></td>
          <td id="file-mlops-c-LC52" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">temp_row</span>[<span class="pl-s1">output_width</span>];<span class="pl-c">//store rows in this</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L53" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="53"></td>
          <td id="file-mlops-c-LC53" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">output_height</span>];<span class="pl-c">//store lists of rows in this</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L54" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="54"></td>
          <td id="file-mlops-c-LC54" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">output_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L55" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="55"></td>
          <td id="file-mlops-c-LC55" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">output_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L56" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="56"></td>
          <td id="file-mlops-c-LC56" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">// first convert all values to float</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L57" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="57"></td>
          <td id="file-mlops-c-LC57" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">temp_row</span>[<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_float</span>(<span class="pl-s1">output</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L58" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="58"></td>
          <td id="file-mlops-c-LC58" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L59" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="59"></td>
          <td id="file-mlops-c-LC59" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-s1">output_width</span>, <span class="pl-s1">temp_row</span>);<span class="pl-c">//convert row to mp list and store into array</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L60" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="60"></td>
          <td id="file-mlops-c-LC60" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L61" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="61"></td>
          <td id="file-mlops-c-LC61" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L62" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="62"></td>
          <td id="file-mlops-c-LC62" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L63" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="63"></td>
          <td id="file-mlops-c-LC63" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-s1">output_height</span>, <span class="pl-s1">output_converted_to_mp</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L64" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="64"></td>
          <td id="file-mlops-c-LC64" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L65" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="65"></td>
          <td id="file-mlops-c-LC65" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L66" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="66"></td>
          <td id="file-mlops-c-LC66" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L67" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="67"></td>
          <td id="file-mlops-c-LC67" class="blob-code blob-code-inner js-file-line"><span class="pl-smi">STATIC</span> <span class="pl-s1">mp_obj_t</span> <span class="pl-en">sum_matrices</span>(<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">matrices</span>, <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">bias</span>) {</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L68" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="68"></td>
          <td id="file-mlops-c-LC68" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert from mpy lists to pointers and mpy float to c float</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L69" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="69"></td>
          <td id="file-mlops-c-LC69" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">bias_f</span> <span class="pl-c1">=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">bias</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L70" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="70"></td>
          <td id="file-mlops-c-LC70" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">matrices_c</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">matrices</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L71" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="71"></td>
          <td id="file-mlops-c-LC71" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">first_matrix</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">matrices_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-c1">0</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L72" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="72"></td>
          <td id="file-mlops-c-LC72" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">first_matrix_first_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">first_matrix</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-c1">0</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L73" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="73"></td>
          <td id="file-mlops-c-LC73" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">num_matrices</span> <span class="pl-c1">=</span> <span class="pl-s1">matrices_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L74" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="74"></td>
          <td id="file-mlops-c-LC74" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">matrix_height</span> <span class="pl-c1">=</span> <span class="pl-s1">first_matrix</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L75" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="75"></td>
          <td id="file-mlops-c-LC75" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">int</span> <span class="pl-s1">matrix_width</span> <span class="pl-c1">=</span> <span class="pl-s1">first_matrix_first_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">len</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L76" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="76"></td>
          <td id="file-mlops-c-LC76" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L77" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="77"></td>
          <td id="file-mlops-c-LC77" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Initialize result matrix with zeroes</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L78" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="78"></td>
          <td id="file-mlops-c-LC78" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">float</span> <span class="pl-s1">result</span>[<span class="pl-s1">matrix_height</span>][<span class="pl-s1">matrix_width</span>];</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L79" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="79"></td>
          <td id="file-mlops-c-LC79" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L80" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="80"></td>
          <td id="file-mlops-c-LC80" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span> (<span class="pl-smi">int</span> <span class="pl-s1">j</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L81" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="81"></td>
          <td id="file-mlops-c-LC81" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">result</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-s1">bias_f</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L82" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="82"></td>
          <td id="file-mlops-c-LC82" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L83" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="83"></td>
          <td id="file-mlops-c-LC83" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L84" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="84"></td>
          <td id="file-mlops-c-LC84" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L85" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="85"></td>
          <td id="file-mlops-c-LC85" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">matrix</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L86" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="86"></td>
          <td id="file-mlops-c-LC86" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_list_t</span> <span class="pl-c1">*</span><span class="pl-s1">matrix_row</span>;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L87" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="87"></td>
          <td id="file-mlops-c-LC87" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">n</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">n</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">num_matrices</span>; <span class="pl-s1">n</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L88" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="88"></td>
          <td id="file-mlops-c-LC88" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">matrix</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">matrices_c</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">n</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L89" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="89"></td>
          <td id="file-mlops-c-LC89" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L90" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="90"></td>
          <td id="file-mlops-c-LC90" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">matrix_row</span> <span class="pl-c1">=</span> <span class="pl-en">MP_OBJ_TO_PTR</span>(<span class="pl-s1">matrix</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">i</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L91" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="91"></td>
          <td id="file-mlops-c-LC91" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L92" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="92"></td>
          <td id="file-mlops-c-LC92" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;&#9;<span class="pl-s1">result</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>] <span class="pl-c1">+=</span> <span class="pl-en">mp_obj_get_float</span>(<span class="pl-s1">matrix_row</span><span class="pl-c1">-&gt;</span><span class="pl-c1">items</span>[<span class="pl-s1">j</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L93" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="93"></td>
          <td id="file-mlops-c-LC93" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L94" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="94"></td>
          <td id="file-mlops-c-LC94" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L95" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="95"></td>
          <td id="file-mlops-c-LC95" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L96" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="96"></td>
          <td id="file-mlops-c-LC96" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L97" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="97"></td>
          <td id="file-mlops-c-LC97" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-c">// Convert result calculated above to mpy compatible object</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L98" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="98"></td>
          <td id="file-mlops-c-LC98" class="blob-code blob-code-inner js-file-line">    <span class="pl-smi">mp_obj_t</span> <span class="pl-s1">temp_row</span>[<span class="pl-s1">matrix_width</span>];<span class="pl-c">//store rows in this</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L99" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="99"></td>
          <td id="file-mlops-c-LC99" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-smi">mp_obj_t</span> <span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">matrix_height</span>];<span class="pl-c">//store lists of rows in this</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L100" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="100"></td>
          <td id="file-mlops-c-LC100" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">i</span><span class="pl-c1">=</span><span class="pl-c1">0</span>; <span class="pl-s1">i</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_height</span>; <span class="pl-s1">i</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L101" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="101"></td>
          <td id="file-mlops-c-LC101" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-k">for</span>(<span class="pl-smi">int</span> <span class="pl-s1">j</span> <span class="pl-c1">=</span> <span class="pl-c1">0</span>; <span class="pl-s1">j</span> <span class="pl-c1">&lt;</span> <span class="pl-s1">matrix_width</span>; <span class="pl-s1">j</span><span class="pl-c1">++</span>){</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L102" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="102"></td>
          <td id="file-mlops-c-LC102" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-c">// first convert all values to float</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L103" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="103"></td>
          <td id="file-mlops-c-LC103" class="blob-code blob-code-inner js-file-line">&#9;&#9;&#9;<span class="pl-s1">temp_row</span>[<span class="pl-s1">j</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_float</span>(<span class="pl-s1">result</span>[<span class="pl-s1">i</span>][<span class="pl-s1">j</span>]);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L104" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="104"></td>
          <td id="file-mlops-c-LC104" class="blob-code blob-code-inner js-file-line">&#9;&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L105" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="105"></td>
          <td id="file-mlops-c-LC105" class="blob-code blob-code-inner js-file-line">&#9;&#9;<span class="pl-s1">output_converted_to_mp</span>[<span class="pl-s1">i</span>] <span class="pl-c1">=</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-s1">matrix_width</span>, <span class="pl-s1">temp_row</span>);<span class="pl-c">//convert row to mp list and store into array</span></td>
        </tr>
        <tr>
          <td id="file-mlops-c-L106" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="106"></td>
          <td id="file-mlops-c-LC106" class="blob-code blob-code-inner js-file-line">&#9;}</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L107" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="107"></td>
          <td id="file-mlops-c-LC107" class="blob-code blob-code-inner js-file-line">&#9;</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L108" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="108"></td>
          <td id="file-mlops-c-LC108" class="blob-code blob-code-inner js-file-line">&#9;<span class="pl-k">return</span> <span class="pl-en">mp_obj_new_list</span>(<span class="pl-s1">matrix_height</span>, <span class="pl-s1">output_converted_to_mp</span>);</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L109" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="109"></td>
          <td id="file-mlops-c-LC109" class="blob-code blob-code-inner js-file-line">
</td>
        </tr>
        <tr>
          <td id="file-mlops-c-L110" class="blob-num js-line-number js-code-nav-line-number js-blob-rnum" data-line-number="110"></td>
          <td id="file-mlops-c-LC110" class="blob-code blob-code-inner js-file-line">}</td>
        </tr>
  </tbody></table>
</div>


    </div>

  </div>
</div>

      </div>
      <div class="gist-meta">
        <a href="https://gist.github.com/Amplify4177/f886102dbd47e9de906c4e445c66286b/raw/7c2cf1be78df8c02bb06d6adc3934ff7f520055d/mlops.c" style="float:right" class="Link--inTextBlock">view raw</a>
        <a href="https://gist.github.com/Amplify4177/f886102dbd47e9de906c4e445c66286b#file-mlops-c" class="Link--inTextBlock">
          mlops.c
        </a>
        hosted with &#10084; by <a class="Link--inTextBlock" href="https://github.com">GitHub</a>
      </div>
    </div>
</div>
</div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Making MicroPython computations run 109x faster]]></title><description><![CDATA[For those not familiar - MicroPython is an implementation of Python developed for microcontrollers. It works pretty well out of the box but I was curious how much faster we could make things run if we tried to optimize it.]]></description><link>https://luvsheth.com/p/making-micropython-computations-run</link><guid isPermaLink="false">https://luvsheth.com/p/making-micropython-computations-run</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sun, 26 Mar 2023 07:07:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/9f86c97f-a044-443d-a1af-b7fab995735d_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For those not familiar - <a href="https://micropython.org">MicroPython</a> is an implementation of Python developed for microcontrollers. It works pretty well out of the box but I was curious how much faster we could make things run if we tried to optimize it.</p><p>There are two things that could be making code run slow:</p><ol><li><p>Waiting for external input like an HTTP request or GPIO button press</p></li><li><p>Lots of computations</p></li></ol><p>To speed up code in scenario #1, you can use <a href="https://docs.micropython.org/en/latest/library/uasyncio.html">asyncio</a> to run code concurrently. There's lots of information about this online so there's no need for me to write about it.</p><p>Here I'm looking at scenario #2 where there's lots of computation going on. Just in case anyone wants to follow along I am using an ESP-WROOM-32 development board to run this code.</p><p>As a spoiler, I tested 3 different methods to improve performance and here are the results I got:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fbRF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fbRF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 424w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 848w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 1272w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fbRF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png" width="924" height="477" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:477,&quot;width&quot;:924,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9841,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fbRF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 424w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 848w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 1272w, https://substackcdn.com/image/fetch/$s_!fbRF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F816eaee0-76fd-4a1b-91bc-788f30e8004e_924x477.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I also provide the complete source towards the end in case you'd like to check the source for more information.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>Baseline Function</h1><p>Let's set up a baseline first.</p><p>Here's a function that tests whether a number is prime or not (<a href="https://www.programiz.com/python-programming/examples/prime-number">source</a>):</p><pre><code>def testPrime(num): 
    if num == 1: 
        # 1 is defined as not prime 
        return False 
         
    elif num &gt; 1: 
        # check for factors 
        for i in range(2, num): 
            if (num % i) == 0: 
                # if factor is found, this is not a prime number 
                return False 
        # No factors found - number is prime 
        return True</code></pre><p>Let's benchmark how fast it runs on MicroPython.</p><p>Here's the test code - we measure how many CPU clock cycles it takes for the function to run and convert it to a milliseconds estimate based on clock frequency.</p><pre><code>def compareRunTime(num): 
    print("------------") 
    print(f"TESTING whether {num} is prime") 
    print("------------") 
    start_time = time.ticks_cpu() 
    output1 = testPrime(num) 
    end_time = time.ticks_cpu() 
    regular = time.ticks_diff(end_time, start_time) # How many clock cycles did it take to run the function 
    time_ms = regular/cpu_frequency*1000 
    print(f"Regular script took {time_ms} ms / {regular} clock cycles")

compareRunTime(71569) # This is a prime number</code></pre><p>Here's the output:</p><pre><code>------------ 
TESTING whether 71569 is prime 
------------ 
Regular script took 487.2375 ms / 77958003 clock cycles</code></pre><p>So our baseline time to check a 5 digit number is 487ms. </p><h1>Native Code Emitter</h1><p>Next we are going to use Python's native code emitter - documentation can be found <a href="https://docs.micropython.org/en/v1.9.3/pyboard/reference/speed_python.html#the-native-code-emitter">here</a>. All we need to do is add a decorator. What this does is converts the code to machine op-codes rather than using Python bytecode as an intermediary which then needs to be converted to machine op-codes (which is what happened when we ran our baseline example). The trade-off here is larger compiled code size which shouldn't really be an issue if you only use this in the performance-critical sections of code.</p><pre><code>@micropython.native 
def testPrimeNative(num):
# No changes to anything below this
    if num == 1: 
        # 1 is defined as not prime 
        return False 
         
    elif num &gt; 1: 
        # check for factors 
        for i in range(2, num): 
            if (num % i) == 0: 
                # if factor is found, this is not a prime number 
                return False 
        # No factors found - number is prime 
        return True</code></pre><p>Making code run with the native emitter is extremely easy - lots of code should run fine without any changes and the only features that can't be used are context managers and generators (so no async code either since that runs as a generator under the hood).</p><p>Here's the performance comparison code in case you want to see it. </p><pre><code>def compareRunTime(num): 
    print("------------") 
    print(f"TESTING whether {num} is prime") 
    print("------------") 
    start_time = time.ticks_cpu() 
    output1 = testPrime(num) 
    end_time = time.ticks_cpu() 
    regular = time.ticks_diff(end_time, start_time) 
    time_ms = regular/cpu_frequency*1000 
    print(f"Regular script took {time_ms} ms / {regular} clock cycles") 
    start_time = time.ticks_cpu() 
    output2 = testPrimeNative(num) 
    end_time = time.ticks_cpu() 
    native = time.ticks_diff(end_time, start_time) 
    time_ms = native/cpu_frequency*1000 
    print(f"Native script took {time_ms} ms / {native} clock cycles")</code></pre><p>And here are the results:</p><pre><code>------------ 
TESTING whether 71569 is prime 
------------ 
Regular script took 487.2414 ms / 77958627 clock cycles 
Native script took 203.7882 ms / 32606107 clock cycles</code></pre><p>So that's over twice as fast and with essentially no changes to the code. </p><h1>Viper Code Emitter</h1><p>Next we can use the viper code emitter. This produces machine op-codes similar to the native emitter but it optimises things further. To do that it needs to know the variable types and you will need to follow a few other restrictions (<a href="http://Like the Native emitter Viper produces machine instructions but further optimisations are performed, substantially increasing performance especially for integer arithmetic and bit manipulations. It is invoked using a decorator:">link</a>). You will have to write your code to work specifically with the viper emitter and it may not run on the regular desktop version of CPython.</p><p>Here is the code:</p><pre><code>@micropython.viper 
def testPrimeViper(num:int) -&gt; bool: 
    if num == 1: 
        # 1 is defined as not prime 
        return False 
         
    elif num &gt; 1: 
        # check for factors 
        for i in range(2, num): 
            if (num % i) == 0: 
                # if factor is found, this is not a prime number 
                return False</code></pre><p>Here are the results:</p><pre><code>------------ 
TESTING whether 71569 is prime 
------------ 
Regular script took 487.2413 ms / 77958605 clock cycles 
Native script took 203.7885 ms / 32606159 clock cycles 
Viper script took 30.02811 ms / 4804497 clock cycles</code></pre><p>That's a lot faster - we are already running 16x faster than the initial MicroPython code and we didn't really have to do too much work.</p><h1>Micropython C module</h1><p>There's one last thing we can do - we can write our function in C and import it into MicroPython and use that to run the calculation. The nice thing about this method is most of the firmware can still be written in MicroPython and you can use all the nice high-level Python features for most of the firmware. You only write the performance-critical sections of code in C.</p><p>Once you have a compiled C module it's pretty simple to use in MicroPython:</p><pre><code>import test_prime_c 
is_prime = test_prime_c.test_prime(71569)</code></pre><p>Compiling it takes a bit more effort, however. You need to set up the toolchain and then write your C module. Setting up the tool-chain shouldn't take more than 2 hours. As for writing the C module - the simple one here took about 5 minutes but something more complex could take considerably longer. I'd recommend using the MicroPython examples (<a href="https://github.com/micropython/micropython/tree/master/examples/natmod">link</a>) and modifying them to suit your needs. Make sure you can compile and import their example module before you try and make your own.</p><p>Here is what the C code looks like (and here is the documentation to start building your own C modules - <a href="https://docs.micropython.org/en/latest/develop/cmodules.html#cmodules">link</a>).</p><p><code>test_prime_c.c</code> shown below.</p><pre><code>// Include the header file to get access to the MicroPython API
#include "py/dynruntime.h"

// Helper function to check whether a number is prime
STATIC mp_int_t prime_helper(mp_int_t x) {
    if (x == 1){
&#9;// 1 is not prime
        return 0;
    }
&#9;for (int i = 2; i&lt;x; i++){
&#9;&#9;if(x%i == 0){
&#9;&#9;&#9;// factor found - not a prime number
&#9;&#9;&#9;return 0;
&#9;&#9;}
&#9;}
&#9;return 1; // if none of the above conditions determined a factor, then this is a prime
}

// This is the function which will be called from Python, as test_prime(x). We pass it a micropython object (everything is an object in python - int is an object of type int)
STATIC mp_obj_t test_prime(mp_obj_t x_obj) {
    // Get the C compatible integer from the MicroPython integer object
    mp_int_t x = mp_obj_get_int(x_obj);
    // Check whether it is prime
    mp_int_t result = prime_helper(x);
    // Convert the result to a MicroPython boolean object and return it
    return mp_obj_new_bool(result);
}

// Define a Python reference to the function above
// so that you can call it through test_prime_c.test_prime
STATIC MP_DEFINE_CONST_FUN_OBJ_1(test_prime_obj, test_prime);

// This is the entry point and is called when the module is imported
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
    // This must be first, it sets up the globals dict and other things
    MP_DYNRUNTIME_INIT_ENTRY

    // Make the function available in the module's namespace
    mp_store_global(MP_QSTR_test_prime, MP_OBJ_FROM_PTR(&amp;test_prime_obj));

    // This must be last, it restores the globals dict
    MP_DYNRUNTIME_INIT_EXIT
}</code></pre><p>We compile that for our target MCU and it will generate a <code>test_prime_c.mpy</code>&nbsp; file that we upload onto our MCU. We can then import the module into MicroPython and start using it like any other module. Here's a copy of the module I compiled for the ESP32: <a href="https://drive.google.com/file/d/1uVOeOjq0oZ9EWXGMCJtm_o8nkC6bpctv/view?usp=sharing">link</a>.</p><p>Here is the performance benchmark. It&#8217;s also printing the results to make sure that all of them return the same result.</p><pre><code>------------ 
TESTING whether 71569 is prime 
------------ 
Regular script took 487.2414 ms / 77958627 clock cycles 
Native script took 203.7882 ms / 32606107 clock cycles 
Viper script took 30.02839 ms / 4804543 clock cycles 
Compiled C module took 4.476794 ms / 716287 clock cycles 
------------ 
RESULTS 
------------ 
True True True True 
------------</code></pre><p>108.8x faster than the baseline - not bad!</p><p>Let's check with a larger number and a smaller number to see how the performance compares for larger and smaller workloads. </p><pre><code>compareRunTime(313) # This is a prime number - should be quick to calculate</code></pre><pre><code>------------ 
TESTING whether 313 is prime 
------------ 
Regular script took 2.238606 ms / 358177 clock cycles 
Native script took 0.9453438 ms / 151255 clock cycles 
Viper script took 0.1852 ms / 29632 clock cycles 
Compiled C module took 0.03605625 ms / 5769 clock cycles 
------------ 
RESULTS 
------------ 
True True True True 
------------</code></pre><pre><code>compareLongRunTime(4951277) # This is a prime number - should take much longer to calculate</code></pre><pre><code>------------ 
TESTING whether 4951277 is prime 
------------ 
Regular script took 34 s 
Native script took 14 s 
Viper script took 2 s 
Compiled C module took 0s / 305.7551 ms  
------------ 
RESULTS 
------------ 
True True True True 
------------</code></pre><p>With a small workload we see a 62x improvement and with a large workload we see a 112x improvement.</p><h1>Conclusion</h1><p>In general I would try and stick to the native emitter or viper emitter because they are decent enough improvements but still quite quick and easy to implement. </p><p>There are also some other things you can do such as caching references to global objects that would make things faster without having to move to C (<a href="https://docs.micropython.org/en/latest/reference/speed_python.html">link</a>). </p><p>However if there are some specific performance critical sections that are too slow then C is worth a shot. I haven't tried accessing hardware through C just yet so that should make an interesting experiment in the future.</p><p>Here are the results of the above tests in graph form.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0MFM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0MFM!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0MFM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png" width="926" height="478" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:478,&quot;width&quot;:926,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:11023,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0MFM!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!0MFM!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4ca16a18-83cc-44a4-b59d-ff31b9d0a8a2_926x478.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cuE1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cuE1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cuE1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png" width="926" height="478" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:478,&quot;width&quot;:926,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:10327,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cuE1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!cuE1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb7d6e9da-9191-4de1-b9b7-6dcc29794329_926x478.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!X7v3!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!X7v3!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!X7v3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png" width="926" height="478" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:478,&quot;width&quot;:926,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9948,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!X7v3!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 424w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 848w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 1272w, https://substackcdn.com/image/fetch/$s_!X7v3!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc61f445e-b989-4e22-9ad7-15c2738a0224_926x478.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In case anyone needs these for reference, here are source files of the micropython test script, the compiled C module, and C module source file:</p><p><a href="https://drive.google.com/file/d/1cgizMqgzCrXdbBOq_vcw6WYsWTxky_Ik/view?usp=sharing">test_prime_script.py</a></p><p><a href="https://drive.google.com/file/d/1Mq9UXMY8huTrHLJVIhSJ7-zr3B4FFL40/view?usp=sharing">test_prime_c.c (uncompiled C code that you could compile)</a></p><p><a href="https://drive.google.com/file/d/1uVOeOjq0oZ9EWXGMCJtm_o8nkC6bpctv/view?usp=sharing">test_prime_c.mpy (compiled C module that you can import onto an ESP-WROOM-32)</a></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p><p></p>]]></content:encoded></item><item><title><![CDATA[Spider Robot Plays the Keyboard]]></title><description><![CDATA[I wanted to make a robot that can play music.&#160; This post talks about what the robot can do so far and what issues remain.]]></description><link>https://luvsheth.com/p/spider-robot-plays-the-keyboard</link><guid isPermaLink="false">https://luvsheth.com/p/spider-robot-plays-the-keyboard</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sun, 12 Feb 2023 06:15:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2f74fbd8-b801-42ae-b57a-55fae071d029_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Current state</h1><p>I wanted to make a robot that can play music.&nbsp; This is what the robot can do so far - there's plenty of issues that need to be ironed out.</p><div id="vimeo-796637413" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;796637413&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/796637413?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p>Because this is not a trivial project, it's got a long way to go before it's complete.&nbsp; However, given how long this post has gotten already it made sense to document the progress so far.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h1>The goal</h1><ul><li><p>My goal with this project was to make a cheap robot that was capable of playing the piano.</p></li><li><p>I wanted to be able to place it anywhere and have it walk to to the piano and then play it</p></li><li><p>I definitely did not want to have a robot with 50 fingers where I just install the robot onto the piano and each finger plays one key - instead I wanted the robot to move it's arm around to play music</p></li><li><p>I wanted to the option to operate these in a swarm later (i.e. many robots coordinate to play music).</p></li></ul><h1>The early choices</h1><ul><li><p>I wanted this to be cheap enough to build a swarm later so I knew I had to minimize the number of servos and use generic/cheap drivers</p></li><li><p>I also decided early on that there would be a "big brain + little brain" control system.</p><ul><li><p>The little brain would take instructions from the big brain about when and where to move it's arms</p></li><li><p>The big brain would detect the location of the piano and the robot through an overhead camera and command to robot to move to it</p></li><li><p>The big brain would then decide what music to play (notes + rhythm) and then tell the little brain how to move it's arms to play that music</p></li><li><p>The big brain can later be extended to control multiple robots at the same time</p></li><li><p>The big brain and little brain would communicate over WiFi</p></li></ul></li></ul><p>This makes the two systems somewhat independent - I just need to write motion control firmware for the robot to allow it to take commands from the big brain and move it's arms around. All the knowledge about what a piano is, what it looks like, how to use it to play music, etc would reside on the big brain.</p><p>However for this to work the the big brain needs to know the position of the robot and the piano somewhat precisely. For this I used Aruco markers - I placed these QR code type labels on the robot and the piano which then allowed me to track their position. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mml2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mml2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 424w, https://substackcdn.com/image/fetch/$s_!mml2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 848w, https://substackcdn.com/image/fetch/$s_!mml2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 1272w, https://substackcdn.com/image/fetch/$s_!mml2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mml2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png" width="410" height="357.7738095238095" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:733,&quot;width&quot;:840,&quot;resizeWidth&quot;:410,&quot;bytes&quot;:794705,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mml2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 424w, https://substackcdn.com/image/fetch/$s_!mml2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 848w, https://substackcdn.com/image/fetch/$s_!mml2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 1272w, https://substackcdn.com/image/fetch/$s_!mml2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F56556148-91d4-47cf-aaa1-c8fb307a42a0_840x733.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The red arrows point to the Aruco tracking markers</figcaption></figure></div><p>To minimize the error in piano location, I added two codes onto the piano far apart from each other. I've only added one Aruco marker onto the robot and it seems to work fine. </p><p>The reason two QR codes is better than one is because we have a much longer distance to calibrate the camera. If we use just one 12mm large code our calibration distance is ~25 pixels but if we use two codes far apart then we get a 180pixel calibration distance and so the impact of having a one or two pixel error is much smaller.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HyZf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HyZf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 424w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 848w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 1272w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HyZf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png" width="1193" height="654" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:654,&quot;width&quot;:1193,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:996558,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HyZf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 424w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 848w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 1272w, https://substackcdn.com/image/fetch/$s_!HyZf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F088f8f5c-5d89-4462-b436-c68daec2628b_1193x654.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Separately, I also wanted to have a digital simulation of the robot. I mostly wanted this for fun but it did end up being useful when I was trying to debug the motion control firmware - more on that later.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ZQEx!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ZQEx!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 424w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 848w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 1272w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ZQEx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png" width="442" height="323.3422818791946" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:545,&quot;width&quot;:745,&quot;resizeWidth&quot;:442,&quot;bytes&quot;:879340,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ZQEx!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 424w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 848w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 1272w, https://substackcdn.com/image/fetch/$s_!ZQEx!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2cb7e0f7-b256-4883-8734-e4f7a960b2a5_745x545.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>The setup</h1><p>It turns out I didn't need to design a robot from scratch. There was a robot available for purchase that matched my requirements quite well - cheap, battery powered, and I could upload custom firmware for it on it&#8217;s ESP8266 controller. This means that I didn't really have too much to do mechanically apart from the fact that this robot came with incorrect and outdated documentation so I had to figure out how a bag of parts goes together to make a robot.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tMDY!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tMDY!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 424w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 848w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 1272w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tMDY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png" width="1099" height="644" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:644,&quot;width&quot;:1099,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:436945,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tMDY!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 424w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 848w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 1272w, https://substackcdn.com/image/fetch/$s_!tMDY!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F39bbcc1a-4d58-4a1b-805b-8aa200160b8e_1099x644.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Camera - at the beginning I used a Logitech C270 webcam since I had one lying around. I later switched to a CMOS camera with a lens to make the position tracking more precise. The CMOS camera was pretty affordable too - about ~40USD including the lens. Neither of them are particularly high end but you can definitely see the difference in detail between the two cameras. The CMOS camera had significant lens distortion which I accounted for through camera calibration.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!VHUT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!VHUT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 424w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 848w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 1272w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!VHUT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png" width="1191" height="632" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:632,&quot;width&quot;:1191,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:446317,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!VHUT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 424w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 848w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 1272w, https://substackcdn.com/image/fetch/$s_!VHUT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f25383e-0cc8-4e3b-a781-14d4688eba5e_1191x632.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Piano - an Akai MPK Mini 2 that I had lying around.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7QfG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7QfG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7QfG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg" width="328" height="231.80769230769232" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1029,&quot;width&quot;:1456,&quot;resizeWidth&quot;:328,&quot;bytes&quot;:166372,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7QfG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 424w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 848w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!7QfG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe8769bd2-7176-4794-804c-9f7de9dd7d19_1500x1060.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Big brain - Python running on my computer</p><p>Connectivity - The robot and the big brain communicate over my home WiFi network.</p><p>Here&#8217;s a diagram showing how the setup works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y_40!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y_40!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y_40!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg" width="1342" height="704" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/bbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:704,&quot;width&quot;:1342,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:93492,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y_40!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 424w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 848w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!Y_40!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fbbcedff7-ad16-41d7-ba03-6e6c6a850720_1342x704.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Robot Simulator</h1><ul><li><p>There are a couple options for robot simulators but I picked <a href="https://cyberbotics.com">Webots</a></p></li><li><p>I set things up so that a lot of the firmware I write for the real robot can be uploaded onto the digitally simulated robot with just a few modifications, this made it pretty useful for debugging firmware issues.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z_Zd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 424w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 848w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 1272w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png" width="1456" height="470" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:470,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:618757,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 424w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 848w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 1272w, https://substackcdn.com/image/fetch/$s_!Z_Zd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F93ce0cc5-41e4-4bb2-b220-90827dfcdee6_1918x619.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One nice benefit of having a simulation was: if I ran into an issue and I wasn't sure if it was a software or hardware issue, I could just run the same code on the simulated robot. If the issue exists on the real robot and not on the simulation then the issue is probably mechanical or electrical. If the issue exists on both then it's more likely to be software related.</p><p>For example I had an issue where the path the robot followed while walking was curved rather than straight. Since I didn't see the issue on the digital simulation it seemed likely it was a physical issue. And it turned out it was - one of the legs was mis-aligned by around 10 degrees and that caused the robot to turn a little bit after each step leading to the curved path.</p><div id="vimeo-796639204" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;796639204&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/796639204?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h1>Robot Firmware</h1><p>I ended up writing custom firmware for the robot.</p><ul><li><p>It was programmed as a state machine with 7 states </p><ul><li><p><em>Standby</em> - do nothing</p></li><li><p><em>Walk forward</em> - continuously walk forward</p></li><li><p><em>Turn left</em> - continuously rotate left</p></li><li><p><em>Turn right</em> - continuously rotate right</p></li><li><p><em>Close stance walk</em> - this is a type of walk where it's front legs are closer to the robot chassis. This is useful because it allows the robot to get closer to the piano.</p></li><li><p><em>Close stance standby</em> - same as above, front legs are closer to the robot chassis but it just stands there waiting</p></li><li><p><em>Music mode</em> - I'll explain this in a minute</p></li></ul></li></ul><h4>Close Stance vs Regular Stance</h4><p>Here's an image that shows the difference between the close stance and regular stance states. The close stance allows the robot to get much closer to the piano and allows it to reach a lot more keys compared to the regular stance where it would just reach 1 to 2 keys.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tb1k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tb1k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 424w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 848w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 1272w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tb1k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png" width="1048" height="577" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:577,&quot;width&quot;:1048,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:392846,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tb1k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 424w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 848w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 1272w, https://substackcdn.com/image/fetch/$s_!tb1k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1bf52077-bf0e-4d1b-83e6-f6dc72adaa30_1048x577.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Music Mode</h4><p>For the robot to play music, it had to have somewhat accurate timing for motion control. If there is supposed to be a 0.25 second gap between two notes that are played then the second note does actually need to be played somewhat close to 0.25 seconds after the first. But the start time of the song can be offset by as much as 5 seconds and it wouldn't be a problem.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!HTrO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!HTrO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 424w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 848w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 1272w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!HTrO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png" width="940" height="523" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:523,&quot;width&quot;:940,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:52029,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!HTrO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 424w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 848w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 1272w, https://substackcdn.com/image/fetch/$s_!HTrO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd9a60f3-05c5-4278-a6b5-e9c4a46f3131_940x523.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">I know this isn&#8217;t an accurate representation of how to read sheet music but it did make visualization easier.</figcaption></figure></div><p>Music mode is a way of loading up commands into the robot's queue so that it can focus on playing music "live". </p><p>The big brain will translate high level commands like "play the note C4" into about 5 to 10 more specific movements such as "lift your left hand by 30&#176; then turn your left arm by 38&#176;" and so on. If we try to issue these commands to the robot exactly at the time the command needs to be executed, WiFi latency + program execution latency become an issue. Both of them are variable enough that it would lead to timing issues where we can't predict exactly when the note will play even if we try and account for the latency. This means we need to queue up these commands for the robot to execute later, when the exact time comes. This means the commands the big brain actually issues to the little brain is closer to "lift your left hand by 30&#176; in 300 milliseconds then turn your left arm by 38&#176; in 650ms".</p><p>And that's what music mode does - commands can be queued up at any time and once the robot switches to music mode it will start executing those commands sequentially. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6rWl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6rWl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 424w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 848w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 1272w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6rWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png" width="1193" height="639" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:639,&quot;width&quot;:1193,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:59046,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6rWl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 424w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 848w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 1272w, https://substackcdn.com/image/fetch/$s_!6rWl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4fc4b277-78dd-494a-80a9-3a247f7a475d_1193x639.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One thing to note here is both the big brain and small brain are keeping track of time. They do this by counting the number of milliseconds that have passed from the moment they get switched on. However because they won't be switched on at the exact same time their internal clocks will not be the same. This means the big brain and little brain need to sync-up about what time it is. When the big brain first connects to the little brain it asks the little brain for the time and keeps track of it. Instead of saying "lift your arm in 300ms", the big brain knows the current time according to the little brain's internal clock is, for example, 11066 milliseconds. So it sends the command "lift your arm at 11366ms". It's done this way to minimize timing errors due to latency variation.</p><h1>Big Brain</h1><p>The big brain has three main purposes:</p><ul><li><p>It is a GUI for me to interact with the robot</p></li><li><p>It commands the robot to walk it to the piano</p></li><li><p>Once at the piano it generates some music and commands the robot to play it</p></li></ul><p>Let's break the three of those down:</p><h4>GUI</h4><pre><code><em>It is a GUI for me to interact with the robot</em></code></pre><p>This one is pretty simple - I built a GUI to make it easier for me to interact with the robot. It allows me to set the robot to a specific state using buttons or allows me to issue high level commands like "GoToKeyboard" after which the big brain will start directing the robot to the keyboard.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MCTO!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MCTO!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 424w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 848w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 1272w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MCTO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png" width="1456" height="783" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:783,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:707214,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MCTO!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 424w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 848w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 1272w, https://substackcdn.com/image/fetch/$s_!MCTO!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4a2eaa7f-55f0-412b-8d53-e19b914f1905_1920x1032.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h4>Walk to piano</h4><pre><code><em>It commands the robot to walk it to the piano</em></code></pre><div id="vimeo-796642433" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;796642433&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/796642433?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><ul><li><p>The big brain knows where the piano is because of the overhead camera. </p><ul><li><p>It uses the camera to locate the two aruco codes on the piano</p></li><li><p>It also knows the dimensions of the piano and exact location of the codes stuck on to the piano. </p></li></ul></li><li><p>It also knows where the robot is because of the aruco code on the robot. </p></li><li><p>It keeps tracking both the robot and piano in real time. It issues commands to the robot such as "turn left, walk straight", etc to direct the robot to the piano</p></li><li><p>There was also some optimization to increase the accuracy of keyboard and spider position tracking by filtering the noisy data</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!T4Fu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!T4Fu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 424w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 848w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 1272w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!T4Fu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png" width="1200" height="674" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:674,&quot;width&quot;:1200,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:587113,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!T4Fu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 424w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 848w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 1272w, https://substackcdn.com/image/fetch/$s_!T4Fu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7631fc9c-4220-4b00-a0d8-16dedab719db_1200x674.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Music and Commands</h2><pre><code><em>Once at the piano it generates some music and instructs the robot on how to play it.</em></code></pre><ul><li><p>It checks which keys are within reach for the robot through inverse kinematics i.e. it tries to calculate how to hit the each key and if no solution exists - it is not within reach.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8oK1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8oK1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 424w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 848w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 1272w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8oK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png" width="1193" height="644" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:644,&quot;width&quot;:1193,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1121164,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8oK1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 424w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 848w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 1272w, https://substackcdn.com/image/fetch/$s_!8oK1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6340a10d-a4a0-41b1-893b-8afeb0cba6b6_1193x644.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>It generates music to be played based on the keys that are within reach i.e. what note should be played at what time (the music it generates is extremely basic at the moment)</p></li><li><p>It converts that music into motion through inverse kinematics. For example - to play note C4 the left arm will have to be move to 30 degrees from resting position and the left finger will need to move down by 15 degrees</p></li><li><p>It does extremely basic collision avoidance eg. it knows to lift up the outer arms sufficiently before moving over the keyboard so as to not crash into it</p></li><li><p>It then streams those commands to the robot to queue them up</p></li></ul><h1>Current state + Issues</h1><p>This is where things are at now:</p><div id="vimeo-797898295" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;797898295&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/797898295?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Plenty of issues that need to be worked on:</p><ul><li><p>It sometimes misses the keys and ends up pressing in between two keys </p><ul><li><p>Potentially need to improve the inverse kinematics algorithm or improve the computer vision computations in the big-brain</p></li></ul></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ndYG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ndYG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 424w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 848w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 1272w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ndYG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png" width="1253" height="698" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:698,&quot;width&quot;:1253,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:1206537,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ndYG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 424w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 848w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 1272w, https://substackcdn.com/image/fetch/$s_!ndYG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1dfd7b14-487c-48a1-b494-705bb105ce98_1253x698.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>It often aims for the correct key but doesn't actually trigger the key press because it either doesn't press down enough or aims too high up on a key where it needs too much force to trigger the key.</p></li></ul><div id="vimeo-796643998" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;796643998&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/796643998?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>The reason for this is there is just a 1mm margin where they key press is triggered. If the arm stops above that then the note won't be triggered. However if it pushes the key below more than 1mm below the trigger point, the key will bottom out and the robot will be pushed away. This means all future key presses will be based on incorrect robot position calculations. Right now we see both these issues, sometimes it presses the key too lightly and sometimes it presses it too hard and moves the spider away a little bit. Those small position changes add up over time.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!7Zpj!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!7Zpj!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 424w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 848w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 1272w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!7Zpj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png" width="1324" height="549" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:549,&quot;width&quot;:1324,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:30675,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!7Zpj!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 424w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 848w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 1272w, https://substackcdn.com/image/fetch/$s_!7Zpj!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd08c1847-5654-4789-b1f7-27cfc67cbe88_1324x549.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>One way to resolve this might be to use a somewhat flexible end effector that can move down and bend away once it hits the bottom of the keystroke. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!r7Qk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!r7Qk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 424w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 848w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 1272w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!r7Qk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png" width="1088" height="538" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:538,&quot;width&quot;:1088,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:345072,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!r7Qk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 424w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 848w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 1272w, https://substackcdn.com/image/fetch/$s_!r7Qk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8b12219a-e149-4b88-a6cc-88600b6b9533_1088x538.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This would also allow me to remove the weights that are currently on the robot since they only exist to reduce how much the robot moves away after it hits the bottom of the stroke.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MRsR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MRsR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 424w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 848w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 1272w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MRsR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png" width="484" height="402" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:402,&quot;width&quot;:484,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:247060,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MRsR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 424w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 848w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 1272w, https://substackcdn.com/image/fetch/$s_!MRsR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0d4f49f8-8fb2-4fbb-8bf9-61b3029e1359_484x402.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>Another issue is the motion doesn't look natural - this doesn't really affect the functionality but small changes to the software might make it seem more natural and fluid. This could be things like:</p><ul><li><p>allowing the arms to rest down when it is not going to play a note for a couple of seconds</p></li><li><p>adding slight movement of the arm between notes </p></li></ul></li></ul><p>All of this is going to be a lot of work to fine tune and it's probably a bit more than I should do for a blog but if I can find the time I will keep making small changes. Let's see how it plays out!</p><p></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://luvsheth.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading luvsheth.com! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Internet of Halloween Costumes]]></title><description><![CDATA[For Halloween I had a pretty geeky costume idea - I wanted to build a costume with lights that anyone could control from their own phone.]]></description><link>https://luvsheth.com/p/internet-of-halloween-costumes</link><guid isPermaLink="false">https://luvsheth.com/p/internet-of-halloween-costumes</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Wed, 02 Nov 2022 12:20:23 GMT</pubDate><enclosure url="https://substackcdn.com/image/vimeo/w_728,c_limit,d_video_placeholder.png/766454565" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>For Halloween I had a pretty geeky costume idea - I wanted to build a costume with lights that anyone could control from their own phone.</p><div id="vimeo-766454354" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;766454354&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/766454354?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><h1>How it works</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TXPe!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TXPe!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 424w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 848w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 1272w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TXPe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png" width="1024" height="577" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:577,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!TXPe!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 424w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 848w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 1272w, https://substackcdn.com/image/fetch/$s_!TXPe!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F46fa4af7-e6fa-4ef2-8e71-f5d4d780786b_1024x577.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Thanks to www.freepik.com for the icons</figcaption></figure></div><ul><li><p>An ESP32 microcontroller is used to control the LEDs.</p></li><li><p>The microcontroller is connected to the internet through my phone hotspot.</p></li><li><p>The microcontroller will constantly check the communication server for messages. Once it gets a message it interprets the command to figure out what, if anything, it should do.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xWeX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xWeX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 424w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 848w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 1272w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xWeX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png" width="694" height="786" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:786,&quot;width&quot;:694,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xWeX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 424w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 848w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 1272w, https://substackcdn.com/image/fetch/$s_!xWeX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F74458806-8896-40ff-90b6-f01ca8e80dfb_694x786.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>On the webapp, I have buttons set up for a couple different effects and pressing any of these will send a message to the MQTT server that tells the microcontroller what to do.</p></li><li><p>Anyone can go to the webapp (which could be hosted on any domain eg. spookyhalloween.com) and control the lights<br><br>Because I am a lot more familiar with Python than Javascript, I felt it was easiest to do the heavy lifting through Python so what the webapp really does is calls a postman script that is written in Python and tells it what message to send to the communication server. I happened to use Google Cloud Functions as my "server" for the postman script.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Xw1C!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Xw1C!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 424w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 848w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 1272w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Xw1C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png" width="1024" height="824" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:824,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Xw1C!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 424w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 848w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 1272w, https://substackcdn.com/image/fetch/$s_!Xw1C!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F13beb048-d02e-45c0-9cb9-aa213738e91f_1024x824.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I could definitely have done this without the postman script but it was much quicker for me to do it this way and because this was just a Halloween costume - quick and easy was the way to go.</p><h1>Demo</h1><p>Here's a longer demo of the costume:</p><div id="vimeo-766454407" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;766454407&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/766454407?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Next I just add on the light diffusers and we are good to go.</p><div id="vimeo-766454565" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;766454565&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/766454565?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h1>What didn't work</h1><ol><li><p>The way you would do this if you could just connect to your home WiFi would be much easier. You wouldn't need an MQTT server - you can just enable port-forwarding on your router and send the HTTP requests directly from the website to your microcontroller. Unfortunately because I had to connect to a phone hotspot this isn't possible. Network providers block incoming requests so any requests sent from the website to the microcontroller over cellular would just by dropped by the network provider. You can buy Machine-To-Machine (<a href="https://www.freeeway.com/what-is-an-m2m-sim-card/">M2M</a>) sim cards but that is both overkill and unnecessary for a Halloween costume so mobile hotspot + MQTT it is!</p></li><li><p>I also tried to use <a href="https://www.arduino.cc/reference/en/libraries/arest/">aREST</a> which is a service that would have made this pretty turnkey but their documentation is sparse and their server seems down.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mV4o!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mV4o!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 424w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 848w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 1272w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mV4o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png" width="1024" height="409" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:409,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mV4o!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 424w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 848w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 1272w, https://substackcdn.com/image/fetch/$s_!mV4o!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7853b53f-bea3-4ef4-8773-fede3c26b6ec_1024x409.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ol start="3"><li><p>As a side note, one nice thing about this project is I didn't really buy (and waste) any parts, just used parts parts that I had lying around. After Halloween, those parts went back into my bin to be used for other projects. This is why I'm using plain old LEDs rather than using WS2812 I2C controlled LEDs where I would have much fewer wires to connect.</p></li></ol>]]></content:encoded></item><item><title><![CDATA[Microfluidic Droplet Generator]]></title><description><![CDATA[This is a follow up to the microfluidics rapid prototyping post.]]></description><link>https://luvsheth.com/p/microfluidic-droplet-generator</link><guid isPermaLink="false">https://luvsheth.com/p/microfluidic-droplet-generator</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Fri, 02 Jul 2021 14:28:02 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/abef5f2b-f6d7-4eb9-bd96-b7d3845b52b5_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This is a follow up to the <a href="https://luvsheth.com/microfluidic-chip-low-volume-rapid-prototyping/">microfluidics rapid prototyping</a> post.</p><p>In this post we will:</p><ol><li><p>Fix the leakage issue</p></li><li><p>Design a basic microfluidic droplet generator (video shown below)</p></li><li><p>Benchmark the performance of the droplet generator to have something to compare future improvements to</p></li></ol><div id="vimeo-677711094" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677711094&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677711094?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><h1>Solving the leakage issue</h1><p>First let's talk about leakage. <br><br>Previously, liquid would sometimes leak out from between the two layers of the circuit like shown here.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ybhz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ybhz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ybhz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg" width="436" height="307.6222222222222" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:508,&quot;width&quot;:720,&quot;resizeWidth&quot;:436,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ybhz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ybhz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff118670e-1536-4a36-9f1c-4c334d21bc8a_720x508.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Adding a screw near each corner and using a nut to clamp down the circuit improved the sealing. I haven't seen much leakage since.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cq3l!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cq3l!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 424w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 848w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 1272w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cq3l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png" width="1456" height="492" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/ebccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:691173,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!cq3l!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 424w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 848w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 1272w, https://substackcdn.com/image/fetch/$s_!cq3l!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Febccaf31-6127-4978-aa65-ca2e6342abbc_1730x584.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Now let's use this to make a droplet generator.</p><h1>Droplet Generator Circuit Overview</h1><p>If you haven't read the previous post - a droplet generator will take two fluids, eg. oil and water, and create small droplets of water inside a stream of oil. Example video shown here (credit: Churchman, Adam H. (2018) <a href="https://en.wikipedia.org/wiki/Doi_(identifier)">doi</a>:<a href="https://doi.org/10.5518%2F153">10.5518/153</a>).</p><div id="vimeo-677713814" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677713814&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677713814?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>This circuit has three input ports - two are used for oil and one for colored water. We use a syringe to provide suction and pull the liquids through to the output port.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Eu51!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Eu51!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 424w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 848w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 1272w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Eu51!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png" width="1010" height="769" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/4b415010-b369-4c0c-995b-b2130b949870_1010x769.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:769,&quot;width&quot;:1010,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Eu51!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 424w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 848w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 1272w, https://substackcdn.com/image/fetch/$s_!Eu51!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4b415010-b369-4c0c-995b-b2130b949870_1010x769.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Next let's create a an internal fluid channel design that actually works. Because prototyping these is really fast, we can just come up with a basic design and iterate over it.</p><h1>Channel Designs</h1><h2>Channel Design #1</h2><p><strong>Design and Expected Behavior</strong></p><p>The first design + how I expected it to behave is illustrated below. I expected the two streams of oil would break the free-flowing stream of red water into droplets around the constriction.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SVQs!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SVQs!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 424w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 848w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 1272w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SVQs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png" width="870" height="588" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:588,&quot;width&quot;:870,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!SVQs!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 424w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 848w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 1272w, https://substackcdn.com/image/fetch/$s_!SVQs!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0d573453-9b50-4a95-9e99-21ee3a0a7c7f_870x588.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Test Outcome</strong></p><p>In reality - the three streams just flow side-by-side. <br><br>Adding red dye to the water makes it thicker (aka more viscous). My theory is this increased viscosity makes it harder to break down into droplets.</p><div id="vimeo-677704677" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677704677&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677704677?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h2>Channel Design #2</h2><p><strong>Design and Expected Behavior</strong></p><p>I thought increasing the flow rate of oil would force the water to break down into droplets. So I made the oil channels wider.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!einR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!einR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 424w, https://substackcdn.com/image/fetch/$s_!einR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 848w, https://substackcdn.com/image/fetch/$s_!einR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 1272w, https://substackcdn.com/image/fetch/$s_!einR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!einR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png" width="1024" height="655" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/d64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:655,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!einR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 424w, https://substackcdn.com/image/fetch/$s_!einR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 848w, https://substackcdn.com/image/fetch/$s_!einR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 1272w, https://substackcdn.com/image/fetch/$s_!einR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd64cea04-001b-4bd5-9456-2d89dde420c3_1024x655.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Test Outcome</strong></p><p>Close - but it turns out the droplets formed before the constriction. The constriction then forced them to combine back into a larger stream of liquid.</p><div id="vimeo-677704763" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677704763&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677704763?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h2>Channel Design #3</h2><p><strong>Design and Expected Behavior</strong></p><p>So I just removed the constriction.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tTua!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tTua!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 424w, https://substackcdn.com/image/fetch/$s_!tTua!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 848w, https://substackcdn.com/image/fetch/$s_!tTua!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 1272w, https://substackcdn.com/image/fetch/$s_!tTua!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tTua!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png" width="824" height="567" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:567,&quot;width&quot;:824,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!tTua!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 424w, https://substackcdn.com/image/fetch/$s_!tTua!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 848w, https://substackcdn.com/image/fetch/$s_!tTua!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 1272w, https://substackcdn.com/image/fetch/$s_!tTua!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4bc08fc4-879c-48bd-b008-f8bc1ec47bf0_824x567.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Test Outcome</strong></p><p>This made the water and 2 oil streams flow side by side. </p><p>Note: You&#8217;ll see little drops of red water coming in from the oil input ports &#8211; this is just because I was also testing whether this could generate oil droplets in a water stream and there was residual water in the oil input ports.</p><div id="vimeo-677704906" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677704906&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677704906?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>However it turns out if we replace water with air, this circuit can form droplets.</p><div id="vimeo-677704846" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677704846&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677704846?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>My theory is the oil stream still wasn't able to break the water into droplets because of the increased viscosity of water after being mixed with dye.</p><h2>Channel Design #4</h2><p><strong>Design and Expected Behavior</strong></p><p>I added a constriction before the intersection to force the water stream to break up into droplets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!83Zc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!83Zc!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 424w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 848w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 1272w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!83Zc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png" width="838" height="559" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:559,&quot;width&quot;:838,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!83Zc!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 424w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 848w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 1272w, https://substackcdn.com/image/fetch/$s_!83Zc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bdbc383-1d32-4517-a126-da53e0374f29_838x559.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Test Outcome</strong></p><p>Which ended up working.</p><div id="vimeo-677711094" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677711094&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677711094?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h1>Performance Benchmarking</h1><p>This isn't a great droplet generator because:</p><ol><li><p>Droplet sizes are inconsistent</p></li><li><p>The droplets are generated quite slowly</p></li></ol><p>This may be because I pull on the syringe manually. This causes the suction pressure to fluctuate - which could be responsible for the inconsistent droplet size.<br><br>But let's add some performance benchmarks anyway so that we have something to compare to in the future.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ju_F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ju_F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 424w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 848w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 1272w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ju_F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png" width="1010" height="769" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:769,&quot;width&quot;:1010,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ju_F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 424w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 848w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 1272w, https://substackcdn.com/image/fetch/$s_!ju_F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F9ed808aa-f68d-48a0-ae10-08608de12d8c_1010x769.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ol><li><p>Droplet generation rate (Hz): How many droplets are formed every second?</p></li><li><p>Droplet volume (&#181;L): How many microliters is each droplet?</p></li></ol><p>Let's start with the results and then I will discuss the measurement method. After that I also talk about about three weird little artifacts you might have noticed while looking at the videos so far.</p><p><strong>Droplet Volume</strong><br>Roughly 0.05&#181;L<br>1 tablespoon of water would create ~300,000 droplets</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mcdz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mcdz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 424w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 848w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 1272w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mcdz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png" width="631" height="375" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:631,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!mcdz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 424w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 848w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 1272w, https://substackcdn.com/image/fetch/$s_!mcdz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F82258522-5fdc-46bc-b24d-65986c0a6870_631x375.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><strong>Droplet Generation Rate</strong><br>Roughly 0.8Hz<br>It would take ~4.3 days to convert 1 tablespoon of water into 300,000 droplets</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!j3A9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!j3A9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 424w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 848w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 1272w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!j3A9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png" width="660" height="401" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/d9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:401,&quot;width&quot;:660,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!j3A9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 424w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 848w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 1272w, https://substackcdn.com/image/fetch/$s_!j3A9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd9241d0f-a5bb-4192-abfd-836a692dbb38_660x401.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Let's talk about measurement methods.</p><h2>Droplet Generation Rate</h2><p>To measure droplet generation rate, we can add a red line and count the time it takes for a droplet to cross the line.</p><div id="vimeo-677705190" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677705190&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677705190?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>The droplet generation frequency is roughly 0.8Hz (i.e. 1 droplet formed every ~1.25 seconds)<br><br></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-KGa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-KGa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 424w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 848w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 1272w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-KGa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png" width="660" height="401" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:401,&quot;width&quot;:660,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-KGa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 424w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 848w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 1272w, https://substackcdn.com/image/fetch/$s_!-KGa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F86ea1fa4-4f5b-4b68-afb1-31b7237fcbc8_660x401.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">"Time" is the difference between the previous droplet crossing the red line and the current droplet crossing the red line.</figcaption></figure></div><h2>Droplet Volume</h2><p>First we need to know the size of one pixel in millimeters. We use a calibration ruler like shown below - 10mm is about 852.53 pixels.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!H-iU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!H-iU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 424w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 848w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 1272w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!H-iU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png" width="1024" height="562" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:562,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!H-iU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 424w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 848w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 1272w, https://substackcdn.com/image/fetch/$s_!H-iU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F48e81cde-3c88-45b5-b3d5-2b031ebe654d_1024x562.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then we calculate the area (in mm2) of the entire region the camera sees.<br>(let's ignore perspective distortion to keep things simple)</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0A0X!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0A0X!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 424w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 848w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 1272w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0A0X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png" width="1024" height="560" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/d32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:560,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!0A0X!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 424w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 848w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 1272w, https://substackcdn.com/image/fetch/$s_!0A0X!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd32abe3f-94d1-444e-b5c0-92bde1ef8019_1024x560.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Then we need to count how many pixels make up one droplet. This particular droplet occupies 1586 pixels</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!cbP1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!cbP1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 424w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 848w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 1272w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!cbP1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png" width="1024" height="573" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:573,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!cbP1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 424w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 848w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 1272w, https://substackcdn.com/image/fetch/$s_!cbP1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F38d549f2-2edf-4a51-ad35-48ba3f141cd9_1024x573.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>After measuring the depth of the channel (0.26mm), combine all the data to calculate the final volume of the droplet</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3O-f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3O-f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 424w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 848w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 1272w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3O-f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png" width="1024" height="428" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/d912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:428,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!3O-f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 424w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 848w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 1272w, https://substackcdn.com/image/fetch/$s_!3O-f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fd912c03b-cc38-486f-9552-feabde93f0bd_1024x428.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Unfortunately the droplet volume isn't very consistent - many are around the ~0.06&#181;L mark with the occasional ~0.02&#181;L droplet. <br><br>Replacing the syringe with a more constant suction source might help improve the droplet volume consistency. Or maybe increasing the suction pressure would prevent the formation of the occasional smaller droplet.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2ulg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2ulg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 424w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 848w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 1272w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2ulg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png" width="631" height="375" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:375,&quot;width&quot;:631,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!2ulg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 424w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 848w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 1272w, https://substackcdn.com/image/fetch/$s_!2ulg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F61bae91d-098a-4d8e-b720-c065ef2f337a_631x375.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Minor Artifacts</h1><p>Three interesting artifacts were seen during the experiment.</p><h2>Droplet Splitting</h2><p>The smaller ~0.02&#181;L droplet is usually formed because an additional small droplet breaks off from the main fluid stream while forming the "normal" droplet. A potential fix to this might be just increasing the suction pressure.</p><div id="vimeo-677705239" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677705239&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677705239?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h2>Air Bubble</h2><p>On the final droplet generator you can see an air bubble enter the flow stream.</p><div id="vimeo-677704629" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677704629&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677704629?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>With the slowed down video shown below you can see the air bubble enter from between the two layers of the circuit.</p><div id="vimeo-677705299" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677705299&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677705299?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Some theories:</p><ol><li><p>Leakage: Maybe a nut wasn't clamped tight enough or the thermal processing had an issue which caused bonding issues between the two layers</p></li><li><p>Trapped Air: Maybe there was a residual packet of air trapped between the layers during fabrication and it was dragged into the flow stream</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6NC0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6NC0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 424w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 848w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 1272w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6NC0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png" width="1024" height="699" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:699,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!6NC0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 424w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 848w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 1272w, https://substackcdn.com/image/fetch/$s_!6NC0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c075525-7952-4d07-b45f-c37f72ab7686_1024x699.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h2>Flow Splitting</h2><p>For channel design #2, the droplet's were merging at the constriction. However after the constriction they split into separate streams around the edges of the channel. This might be because the channel is deeper around the edges - but that needs to be confirmed through testing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!K7om!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!K7om!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 424w, https://substackcdn.com/image/fetch/$s_!K7om!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 848w, https://substackcdn.com/image/fetch/$s_!K7om!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 1272w, https://substackcdn.com/image/fetch/$s_!K7om!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!K7om!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png" width="902" height="576" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/a1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:576,&quot;width&quot;:902,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!K7om!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 424w, https://substackcdn.com/image/fetch/$s_!K7om!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 848w, https://substackcdn.com/image/fetch/$s_!K7om!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 1272w, https://substackcdn.com/image/fetch/$s_!K7om!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa1746f5d-8051-4a6b-a6e8-f880691483d1_902x576.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div>]]></content:encoded></item><item><title><![CDATA[Soap Powered Propulsion]]></title><description><![CDATA[It starts with a primary school science experiment]]></description><link>https://luvsheth.com/p/soap-powered-propulsion</link><guid isPermaLink="false">https://luvsheth.com/p/soap-powered-propulsion</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sun, 28 Mar 2021 14:26:18 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/2d56242d-eb04-4815-b34d-c6cbc2aa3eaa_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>It starts with a primary school science experiment</h1><p>Someone showed me a science experiment I had never seen before. The setup is: you have a bowl with water in it and you grind some pepper onto the surface. Watch what happens when you add a little bit of soap onto the surface of the water:</p><div id="vimeo-677703579" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703579&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703579?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><h1>What causes this to happen?</h1><p>When soap is introduced onto the surface of water, it will quickly start spreading over the surface. The macro view of why this happens is that the soap film reduces the surface tension of the water and puts it into a lower energy state. Things prefer to be at a lower energy state the same way a ball at the top of a hill will roll downhill.</p><p>The micro view is that soap molecules have both a hydrophilic end and a hydrophobic end. The way this interacts with the water is what causes the soap film to spread on the water surface.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9jU6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9jU6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 424w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 848w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 1272w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9jU6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png" width="447" height="130" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/eabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:130,&quot;width&quot;:447,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9jU6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 424w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 848w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 1272w, https://substackcdn.com/image/fetch/$s_!9jU6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Feabd3156-f0ec-4285-8666-5a42ec71c5a3_447x130.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a><figcaption class="image-caption">Picture Credit: <a href="https://www.essentialchemicalindustry.org/materials-and-applications/surfactants.html">essentialchemicalindustry.org</a></figcaption></figure></div><p>Here&#8217;s a more detailed explanation for anyone interested:</p><div id="youtube2-UU9ij_z6jXQ" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;UU9ij_z6jXQ&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/UU9ij_z6jXQ?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><h1>Can this be used to move objects?</h1><p>After looking at the initial experiment, I wondered if this could be used to propel an object forward. As it turns out, it can:</p><div id="vimeo-677703510" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703510&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703510?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>But this still feels like cheating because the soap propels the object forward and I put it there using my hand. The easy solution is to add soap onto the "boat" and use a wick to release the soap into the water slowly.</p><div id="vimeo-677703842" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703842&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703842?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h1>Controlling the motion</h1><p>This is getting better, but there's no way to control when the boat moves forward.</p><p>It would be really cool if we had electronics that dipped soap onto the water only when we wanted it to move. First though, would this even move if it had the weight of electronics on it?</p><div id="vimeo-677703739" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703739&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703739?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>The test above shows that 15gms is a reasonable weight limit for a 8cm x 8cm square of foam.</p><p>Next we need to whip up some electronics.</p><p>To communicate with the micro-controller I would normally pick Bluetooth, Wifi, or USB. But because of the weight limit a WiFi module would be too heavy. Instead I went with a light sensor. I shine a laser onto the light sensor when I want the boat to move. I've shown an example video of an older prototype below. This one doesn't have soap and so doesn't move.</p><div id="vimeo-677703682" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703682&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703682?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>For the actuator I used a piezo-vibrator because it was the lightest moving thing I could find. Because vibrators aren't really designed for this use case, I had to try a bunch of different actuator combinations for this to work. The final set-up looked like this (the boat doesn't move because no soap is used in this demo):</p><div id="vimeo-677703290" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703290&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703290?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>It's a vibrator on a piece of paper that acts like a lever and also has a thin metal rod attached to it. The vibrator moving up and down moves the paper, which amplifies the motion and also moves the metal rod. I dab a bit of soap on to the metal road so that the soap only touches the water when the vibrator is on.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!c8oJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!c8oJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 424w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 848w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 1272w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!c8oJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png" width="973" height="750" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:750,&quot;width&quot;:973,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!c8oJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 424w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 848w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 1272w, https://substackcdn.com/image/fetch/$s_!c8oJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F97e958cb-d5e9-4a73-9898-4ade834b7375_973x750.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Final Result</h1><p>Here's the final result in action!</p><div id="vimeo-677703640" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703640&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703640?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>It would be really cool if we could also stop the boat; but once the soap touches the water it continues getting drawn in to the water. We could likely solve this issue with a vibration setup that has a larger range of motion. Another issue is that the soap runs out in the demo above. I would probably connect a larger soap source to the actuator through some tubes or a wick.</p><p>For the moment, I'm quite happy with where this got. In the future if I have the time to find or make a better actuator I might test it out in a similar system to try and improve it.</p><h1>Happy accident</h1><p>For now, here's another prototype that had a really interesting outcome. The actuator had a flap that acted like oars on a boat and this let the boat move forward without any soap involved.</p><div id="vimeo-677703337" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703337&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703337?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Here it is in action below.</p><div id="vimeo-677703369" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677703369&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677703369?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div>]]></content:encoded></item><item><title><![CDATA[Fixing a Laser Cutter]]></title><description><![CDATA[Laser cutting is hands down my favorite way of prototyping things.]]></description><link>https://luvsheth.com/p/fixing-a-laser-cutter</link><guid isPermaLink="false">https://luvsheth.com/p/fixing-a-laser-cutter</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sat, 27 Mar 2021 09:36:20 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/1d18c669-efd0-4a25-96e3-c4e7b053a160_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Laser cutting is hands down my favorite way of prototyping things. It takes minutes to make new iterations of a design compared to the hours a 3D printer might need. Recently the laser cutter at the makerspace broke down and I was asked to have a look at it. Here's how I went about debugging and fixing it.</p><h1>What's the problem?</h1><p>I consider technical communication extremely important. I always like to show a video that clearly demonstrates what the problem I'm solving is.</p><div id="vimeo-677699249" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677699249&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677699249?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p>In this case, it's quite simple. The laser cutter did nothing.</p><h1>Why doesn't it work?</h1><p>The first thing to check was the control box.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Asn-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Asn-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 424w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 848w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 1272w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Asn-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png" width="544" height="734" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/81605184-8477-4da6-a752-4959c967dbc4_544x734.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:734,&quot;width&quot;:544,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Asn-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 424w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 848w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 1272w, https://substackcdn.com/image/fetch/$s_!Asn-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F81605184-8477-4da6-a752-4959c967dbc4_544x734.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The control box is the nervous system of the laser cutter, it takes in instructions (G-code) from the computer and converts it into electrical currents that move the motors and turns the laser on and off.</p><p>It turns out, the control box had power coming in to it but no power coming out of it.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ihz-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ihz-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 424w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 848w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 1272w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ihz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png" width="609" height="688" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:688,&quot;width&quot;:609,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!ihz-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 424w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 848w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 1272w, https://substackcdn.com/image/fetch/$s_!ihz-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c95f2bc-3221-4bce-b4e8-50fdf2ec7966_609x688.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This means that the problem very likely lies with the control box. It would be pretty simple to just swap out the control box for a new one. However for environmental reasons and because debugging broken machines is often interesting I decided to give it a shot and try to fix it.</p><h1>What's a control box anyway?</h1><p>Before proceeding I'm going to provide a quick rundown of what's going on in the control box:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9DhX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9DhX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 424w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 848w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 1272w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9DhX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png" width="947" height="712" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/05e34208-1388-4806-8644-78c872eb58fa_947x712.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:712,&quot;width&quot;:947,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9DhX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 424w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 848w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 1272w, https://substackcdn.com/image/fetch/$s_!9DhX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F05e34208-1388-4806-8644-78c872eb58fa_947x712.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The X/Y/Z/U outputs control the X/Y/Z/U axis motors. The X/Y motors control the position of the laser head. The Z motor controls the height of the platform. The U axis is a rotation axis and on this particular machine connects to nothing.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!53CD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!53CD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 424w, https://substackcdn.com/image/fetch/$s_!53CD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 848w, https://substackcdn.com/image/fetch/$s_!53CD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 1272w, https://substackcdn.com/image/fetch/$s_!53CD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!53CD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png" width="937" height="813" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:813,&quot;width&quot;:937,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!53CD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 424w, https://substackcdn.com/image/fetch/$s_!53CD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 848w, https://substackcdn.com/image/fetch/$s_!53CD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 1272w, https://substackcdn.com/image/fetch/$s_!53CD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F0bbb62f6-b8c1-4f7a-89b3-97ad7908ab1d_937x813.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>At the limits of motion of the laser cutter, there are switches. If the laser head ever hits these switches, it stops moving. This is a safety feature and ensures the machine doesn't destroy itself. It's also essential for calibration so that the laser cutter can figure out where the laser head is whenever it needs to.</p><div id="vimeo-677699301" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677699301&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677699301?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>The display port just connects to an interface that provides cutting parameter information and allows the user to control the laser cutter (i.e. start cutting, move the laser head, etc).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xm44!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xm44!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 424w, https://substackcdn.com/image/fetch/$s_!xm44!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 848w, https://substackcdn.com/image/fetch/$s_!xm44!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 1272w, https://substackcdn.com/image/fetch/$s_!xm44!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xm44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png" width="1024" height="768" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/a5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xm44!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 424w, https://substackcdn.com/image/fetch/$s_!xm44!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 848w, https://substackcdn.com/image/fetch/$s_!xm44!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 1272w, https://substackcdn.com/image/fetch/$s_!xm44!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fa5a4a3ee-b5c8-4fc8-be02-fd8b7d8878a0_1024x768.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Why won't the control box control stuff?</h1><p>As it turns out, the control box was designed to receive 24 volts but had 36V going in instead. I suspected this high voltage had fried something inside. I opened up the circuit to have a look at what's going on.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!dsZT!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!dsZT!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 424w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 848w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 1272w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!dsZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png" width="1024" height="716" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:716,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!dsZT!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 424w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 848w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 1272w, https://substackcdn.com/image/fetch/$s_!dsZT!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F72b6c113-1c32-412b-990d-64e6cd21b76e_1024x716.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>There were a whole bunch of communication and control chips but because everything on the board stopped working, I had a hunch that the board's power circuit was blown and decided to poke around there. I connected the control board to a power supply and started testing components one at a time. These were the issues I found:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AI0-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AI0-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 424w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 848w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 1272w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AI0-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png" width="1019" height="293" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:293,&quot;width&quot;:1019,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!AI0-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 424w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 848w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 1272w, https://substackcdn.com/image/fetch/$s_!AI0-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F21aa84a8-878d-49b2-a235-4cbf2931079c_1019x293.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>The voltage regulator is supposed to take in 24V and convert it to 5V for other chips on the circuit to use as a power source. This voltage regulator had internally shorted and just sent out 24V instead of 5V.</p></li><li><p>This diode seems like it's is supposed to prevent power flowing into the coil cell when the circuit is connected to a power supply. In this case it had internally shorted and just caused the whole circuit to short out.</p></li><li><p>Coin cell was out of charge. It was at 0.4V instead of 3V.</p></li></ul><p>While I don't think the coin cell plays a particularly important role in this control circuit it was cheap enough to replace anyway. The other two, though were either the cause of or related to why the laser cutter wouldn't work.</p><p>At this point I also looked at the datasheet of the voltage regulator to see if the 36V power supply was what damaged it. As it turns out, this voltage regulator could handle voltages of up to 40V, so feeding it 36V wasn't a problem.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MG60!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MG60!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 424w, https://substackcdn.com/image/fetch/$s_!MG60!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 848w, https://substackcdn.com/image/fetch/$s_!MG60!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 1272w, https://substackcdn.com/image/fetch/$s_!MG60!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MG60!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png" width="772" height="499" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:499,&quot;width&quot;:772,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!MG60!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 424w, https://substackcdn.com/image/fetch/$s_!MG60!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 848w, https://substackcdn.com/image/fetch/$s_!MG60!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 1272w, https://substackcdn.com/image/fetch/$s_!MG60!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F58b80eac-484a-4ee4-914b-bd256ea16b4b_772x499.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I'm still not quite sure what caused these components to fail but for now I'm going to chalk it up to them just being old. If this fails again I can try and figure out what's causing the failure.</p><h1>Repair</h1><p>I ordered the 3 damaged components off Taobao and replaced them. I was a bit worried that once I fixed this, other issues would crop up. However the control board now worked on my desk, so it was time to plug it back into the laser cutter.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!-Rkf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!-Rkf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 424w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 848w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 1272w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!-Rkf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png" width="964" height="582" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:582,&quot;width&quot;:964,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!-Rkf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 424w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 848w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 1272w, https://substackcdn.com/image/fetch/$s_!-Rkf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7b2b02ba-4478-4bb0-bf29-8a5102fdd2dc_964x582.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>I decided to connect the motors back one at a time so that if something broke, the damage would be limited to just a few components.</p><p>Turns out everything worked fine and the laser cutter was back in action!</p><div id="vimeo-677699198" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677699198&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677699198?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div>]]></content:encoded></item><item><title><![CDATA[Chinese <> English Technical Dictionary App Prototype]]></title><description><![CDATA[Learning Chinese in the context of engineering gets hard because many translation/dictionary resources are too general purpose. I have always wanted a dictionary that translates technical words that I use often - so now it's time to build one! If you want to browse around the app while you read this post, here's the link (try it on your phone!):]]></description><link>https://luvsheth.com/p/chinese-english-technical-dictionary-app-prototype</link><guid isPermaLink="false">https://luvsheth.com/p/chinese-english-technical-dictionary-app-prototype</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Sat, 06 Mar 2021 03:15:31 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f1a3a63b-e28e-48b1-82ab-d1cb697a0547_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Learning Chinese in the context of engineering gets hard because many translation/dictionary resources are too general purpose. I have always wanted a dictionary that translates technical words that I use often - so now it's time to build one!</p><p>If you want to browse around the app while you read this post, here's the link (try it on your phone!): <a href="https://fearless-expert-2751.glideapp.io/">https://fearless-expert-2751.glideapp.io/</a></p><p> [lwptoc]</p><h1>App Prototyping</h1><p>I decided to use <a href="https://www.glideapps.com/">Glide</a> to build the app prototype. It involves very little coding and made the whole process extremely quick and easy.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!lyqf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!lyqf!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 424w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 848w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 1272w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!lyqf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png" width="1024" height="447" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/c8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:447,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Glide App Builder Interface&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Glide App Builder Interface" title="Glide App Builder Interface" srcset="https://substackcdn.com/image/fetch/$s_!lyqf!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 424w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 848w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 1272w, https://substackcdn.com/image/fetch/$s_!lyqf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fc8a59cc4-e9ee-4212-a77b-fdcf6977fb30_1024x447.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is what I considered essential to making the dictionary usable:</p><ul><li><p>I must be able to search in English, Chinese, and pinyin. Sometimes I hear a word I haven't heard before and know only the sound - it's important to be able to look these words up using pinyin.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!IeqC!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!IeqC!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 424w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 848w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 1272w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!IeqC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png" width="327" height="300.45148514851485" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:464,&quot;width&quot;:505,&quot;resizeWidth&quot;:327,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Pinyin Search Function&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Pinyin Search Function" title="Pinyin Search Function" srcset="https://substackcdn.com/image/fetch/$s_!IeqC!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 424w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 848w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 1272w, https://substackcdn.com/image/fetch/$s_!IeqC!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5c683daf-2c15-4a46-8ed8-7aad0802e3e0_505x464.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>After looking up a word, I wanted to be able to hear how it sounds. So I wanted audio to show how to pronounce each word in Chinese.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1Vin!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1Vin!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 424w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 848w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 1272w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1Vin!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png" width="321" height="283.34791252485087" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:444,&quot;width&quot;:503,&quot;resizeWidth&quot;:321,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;Interface screenshot that shows how the pronunciation audio can be played&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="Interface screenshot that shows how the pronunciation audio can be played" title="Interface screenshot that shows how the pronunciation audio can be played" srcset="https://substackcdn.com/image/fetch/$s_!1Vin!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 424w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 848w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 1272w, https://substackcdn.com/image/fetch/$s_!1Vin!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff3add6e0-8402-454b-b95a-0f74d0d34238_503x444.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>I wanted to leave space in the app for usage examples later since I know some words would need clarification</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!L26F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!L26F!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 424w, https://substackcdn.com/image/fetch/$s_!L26F!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 848w, https://substackcdn.com/image/fetch/$s_!L26F!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 1272w, https://substackcdn.com/image/fetch/$s_!L26F!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!L26F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png" width="310" height="305.04" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/dee191e6-9ca1-4996-886c-4b6273c23714_500x492.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:492,&quot;width&quot;:500,&quot;resizeWidth&quot;:310,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!L26F!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 424w, https://substackcdn.com/image/fetch/$s_!L26F!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 848w, https://substackcdn.com/image/fetch/$s_!L26F!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 1272w, https://substackcdn.com/image/fetch/$s_!L26F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fdee191e6-9ca1-4996-886c-4b6273c23714_500x492.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><ul><li><p>I wanted to leave space for notes</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!phb_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!phb_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 424w, https://substackcdn.com/image/fetch/$s_!phb_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 848w, https://substackcdn.com/image/fetch/$s_!phb_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 1272w, https://substackcdn.com/image/fetch/$s_!phb_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!phb_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png" width="308" height="385.6260162601626" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:616,&quot;width&quot;:492,&quot;resizeWidth&quot;:308,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!phb_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 424w, https://substackcdn.com/image/fetch/$s_!phb_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 848w, https://substackcdn.com/image/fetch/$s_!phb_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 1272w, https://substackcdn.com/image/fetch/$s_!phb_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6973312c-3f96-49ef-8ca6-8f590bf4d524_492x616.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h1>Making it Useable</h1><p>With the overall structure in place, there were 3 things I had to do:</p><ol><li><p>Create a list of words and their translations</p></li><li><p>Generate related information such as pinyin and the audio file</p></li><li><p>Import all this data into Glide</p></li></ol><h2>Word &lt;&gt; Translation Database</h2><p>Unfortunately there was no magic here. I'm only building this because automatic translations don't live up to my expectations. So I had to take the old fashioned route and manually get the right translation(s) for each word I wanted to add.</p><h2>Pinyin and Audio</h2><p>I used Python to create a script that:</p><ul><li><p>Got pinyin information from Chinese characters (&#35013;&#37197; &gt; zhu&#257;ngp&#232;i)</p></li><li><p>Generated searchable pinyin (zhu&#257;ngp&#232;i &gt; zhuangpei zhuang pei) because...</p><ul><li><p>It would be ridiculous to type zhu&#257;ngp&#232;i into the search bar, I would rather just type zhuangpei</p></li><li><p>I should get the same result whether I type zhuangpei or zhuang pei - so I generated all the variants of where the spaces could be to use for search purposes later. This is a slightly roundabout way of doing it but I've had to do it due to a limitation of the search function in Glide.</p></li></ul></li><li><p>Generated a sound file that I would upload onto my server (eg. www.luvsheth.com/TranslationAppAudio/FILENAME)</p></li><li><p>Added a link to the sound file so that the app knows where to look for the audio</p></li></ul><h2>Data Import</h2><p>Unfortunately Glide doesn't offer data import just yet, so I had to create an interesting workaround... I created a script that would load up an Excel sheet and paste it into Glide one entry at a time. Video shown below.</p><div id="vimeo-677697227" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677697227&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677697227?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><h1>Result</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Z1MZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 424w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 848w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 1272w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png" width="1024" height="724" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:724,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;A picture showing the Chinese Technical Dictionary app in use&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="A picture showing the Chinese Technical Dictionary app in use" title="A picture showing the Chinese Technical Dictionary app in use" srcset="https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 424w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 848w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 1272w, https://substackcdn.com/image/fetch/$s_!Z1MZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8d735c0c-68c6-4bbe-9f0a-a3071f8e891d_1024x724.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is the first app I've built and tools like Glide have made it very easy to do. My future goal for this is to just keep building a larger database of words. Right now the only category that really has entries is CAD but I'd also like to add words for Injection Molding, Manufacturing &amp; Production, etc.</p><p>I will also import this database into my daily use Chinese dictionary app; but it was fun creating this prototype anyway. I think I will continue to use this as a standalone "engineering dictionary" app as well because sometimes having too many words to search from adds many irrelevant words to the search results: like shown below for &#35013;&#37197;/zhu&#257;ngp&#232;i.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nFp0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nFp0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 424w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 848w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 1272w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nFp0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png" width="1024" height="461" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:461,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!nFp0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 424w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 848w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 1272w, https://substackcdn.com/image/fetch/$s_!nFp0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F7f8ed34b-0cb5-436d-8b15-4b0682189c7b_1024x461.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Credit to <a href="https://www.mdbg.net/chinese/dictionary">mdbg.net</a> for hosting an amazing Chinese dictionary!</figcaption></figure></div>]]></content:encoded></item><item><title><![CDATA[Microfluidic Chip Low Volume Rapid Prototyping]]></title><description><![CDATA[Microfluidic chips find applications in bio-sensors and PCR tests among many others. I personally find them extremely interesting because they lie at the intersection of life sciences and electronic/mechanical engineering. To get started with microfluidics, the first step I needed to take was to find a way to prototype these chips at low volumes.]]></description><link>https://luvsheth.com/p/microfluidic-chip-low-volume-rapid-prototyping</link><guid isPermaLink="false">https://luvsheth.com/p/microfluidic-chip-low-volume-rapid-prototyping</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Tue, 09 Feb 2021 15:12:03 GMT</pubDate><enclosure url="https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/a381ad95-9f98-40ef-bd6f-853366b635b8_1456x1048.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microfluidic chips find applications in bio-sensors and PCR tests among many others. I personally find them extremely interesting because they lie at the intersection of life sciences and electronic/mechanical engineering. To get started with microfluidics, the first step I needed to take was to find a way to prototype these chips at low volumes.</p><p>First, just in case...</p><h1>What is a microfluidic chip?</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NHF_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NHF_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NHF_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg" width="729" height="535" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:535,&quot;width&quot;:729,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!NHF_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 424w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 848w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!NHF_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F30664475-4cb2-41b5-9a7a-14549a24de97_729x535.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Picture credit: Dr. Sven Tombrink, Process Engineer iX-factory GmbH</figcaption></figure></div><p>Think of a microfluidic chip as a PCB / circuit-board for fluids. It will route fluids from one location to another. Just like PCBs, microfluidic chips also have components built into them that perform functions beyond just transporting fluid from one location to another. One example of such a component would be a bubble generator that takes an incoming continuous fluid stream and converts it into discrete bubbles like in the video below (credit: Churchman, Adam H. (2018) <a href="https://en.wikipedia.org/wiki/Doi_(identifier)">doi</a>:<a href="https://doi.org/10.5518%2F153">10.5518/153</a>).</p><div id="vimeo-677713814" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677713814&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677713814?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><h1>Microfluidic Chip Structure</h1><p>Microfluidic chips can be manufactured in many different ways all with their own unique advantages. I've shown the structure of my setup below.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!F4T2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!F4T2!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 424w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 848w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 1272w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!F4T2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png" width="828" height="482" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/04ad3619-a566-4d31-972c-98667803eb13_828x482.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:482,&quot;width&quot;:828,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!F4T2!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 424w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 848w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 1272w, https://substackcdn.com/image/fetch/$s_!F4T2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04ad3619-a566-4d31-972c-98667803eb13_828x482.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">This particular circuit just transports fluid from the entry to the exit without doing much else in between</figcaption></figure></div><p>We have two soft layers sandwiched between two hard plastic layers.</p><p>The circuit pattern is etched onto the bottom soft layer and entry/exit ports for the liquid are cut out of the top plastic and soft layers. The whole fabrication process is performed on a laser cutter. There is also post-processing in the form of applying pressure and heat onto the setup so as to ensure that the fluid channels seal properly.</p><p>The primary purpose of the top soft layer is to help the circuit seal. Ideally I would also want another soft layer with no etching on it between the bottom soft and backing layers - unfortunately this ended up causing manufacturing issues.</p><h1>Prototyping Issues</h1><p>As usual, there were plenty of issues I encountered during prototyping, the ones below were interesting enough to mention. Feel free to skip to the end of the article to see the final result.</p><h2>Soft Layer Material Selection</h2><p>There were three considerations with selecting the right material for the soft layer.</p><ul><li><p>The soft layer must be soft enough to seal but not so soft that it deforms during post processing or handling</p></li><li><p>It must be possible to safely etch away the soft layer using a laser cutter (specifically - the one already in the workshop)</p></li><li><p>It must be possible to somehow bond this material to the backing plastic</p></li></ul><h2>Inconsistent Channel Width</h2><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8PL-!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8PL-!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 424w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 848w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 1272w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8PL-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png" width="507" height="225" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:225,&quot;width&quot;:507,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!8PL-!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 424w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 848w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 1272w, https://substackcdn.com/image/fetch/$s_!8PL-!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F046efe36-3af1-44fe-a6e1-75b236fb852e_507x225.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>The soft layer is etched with a laser cutter. The laser cutter I am using slows down as it approaches a sharp turn so that it can make an accurate adjustment to it's direction when it's time to turn. This causes heat to build up over the region where the laser is travelling slowly and takes away more material compared to other areas. This issue was mostly harmless so I ignored it at first but eventually found a way to solve it while working on the next issue.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!eJpF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!eJpF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 424w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 848w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 1272w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!eJpF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png" width="507" height="254" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:254,&quot;width&quot;:507,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!eJpF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 424w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 848w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 1272w, https://substackcdn.com/image/fetch/$s_!eJpF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F77c885d3-d592-4719-839e-5dcf9086e42d_507x254.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The laser path is shown on the upper image with the regions where the laser slows down highlighted in red. You can see the thicker channel widths in the corresponding areas in the lower image.</figcaption></figure></div><h2>Cutting Through The Backing Layers</h2><div id="vimeo-677694056" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677694056&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677694056?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Another side effect of the slow down mentioned above is that if it slowed down enough, it would cut right through the backing layer and allow liquid to leak out the back. This issue was solved by reducing the power of the laser only when it slowed down. This also mostly resolved the previously mentioned issue with channel width consistency.</p><h2>Blocked Channel</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pDNX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pDNX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 424w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 848w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 1272w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pDNX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png" width="1024" height="666" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:666,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!pDNX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 424w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 848w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 1272w, https://substackcdn.com/image/fetch/$s_!pDNX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4612d5aa-11c5-42bc-b943-f43552f10c9b_1024x666.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If the heat and pressure applied during post-processing are too high then we will end up with the soft layers melting into the etched channels and extruding out of every opening - rendering the circuit blocked and useless. The channels are about 0.25mm wide, so it doesn't take much to accidentally block them.</p><h2>Layer Delamination Leakage</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xhcZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xhcZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xhcZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg" width="720" height="508" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:508,&quot;width&quot;:720,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!xhcZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 424w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 848w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!xhcZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F04c0f297-e580-4de3-ab2f-6c72f904caa6_720x508.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>If the seal between the two soft layers isn't very good then liquid will very easily find it's way around the channels.</p><p>While I have made some effort to improve this seal through post processing, it's quite hard to create a perfect seal and even good seals seem to eventually break.</p><div id="vimeo-677694158" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677694158&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677694158?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>My current hypothesis on why this happens is: there are small imperfections in the seal between the two soft layers. As the fluid flows under pressure, these small imperfections force the two layers apart (like using a wedge to split wood). This causes the gap to become even bigger and makes it even easier to force the two layers apart until eventually liquid leaks out the side.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!9RxG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!9RxG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 424w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 848w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 1272w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!9RxG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png" width="1024" height="747" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:747,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!9RxG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 424w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 848w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 1272w, https://substackcdn.com/image/fetch/$s_!9RxG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F4db77f26-0b90-42bd-a745-e33fc4dff5e9_1024x747.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A quick and hacky way to solve this for now is to just seal off the sides of the chip and that way the liquid (mostly) won't go down that path. This solution isn't very good though as it isn't reliable and still sometimes leads to minor leakage out of the channels (but not out of the sides). I don't like this as it's more of a band-aid than a solution to the core issue, so in the future I will likely try and find a better way to solve this.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!WyLl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!WyLl!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 424w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 848w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 1272w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!WyLl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png" width="1024" height="594" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/6823773e-a249-423f-8265-793c5beafdf4_1024x594.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:594,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!WyLl!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 424w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 848w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 1272w, https://substackcdn.com/image/fetch/$s_!WyLl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F6823773e-a249-423f-8265-793c5beafdf4_1024x594.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Current fix for the delamination leakage issue</figcaption></figure></div><h1>Prototype and Conclusion</h1><div id="vimeo-677694106" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677694106&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:true}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677694106?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" loading="lazy"></iframe></div></div><p>Overall I'm quite excited about how this turned out - especially the ~0.25mm channel width that was achieved was significantly better than expected. This is also a very quick and efficient way of fabricating these chips - it takes just about 15 minutes to make a one-off chip. The delamination issue issue isn't completely resolved, so that's probably going to be my main focus for the next attempt.</p><p>After that I would be very interested in trying to etch a valve or droplet generator right into the soft layers without adding any external devices.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Jq0f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Jq0f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 424w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 848w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 1272w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Jq0f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png" width="1024" height="619" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:619,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!Jq0f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 424w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 848w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 1272w, https://substackcdn.com/image/fetch/$s_!Jq0f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F5575ee80-89b0-44af-8fb2-96595307c159_1024x619.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Measurement of the channel width of the final prototype chip</figcaption></figure></div>]]></content:encoded></item><item><title><![CDATA[Using a Contact Mic to Turn Any Object Into a Musical Instrument]]></title><description><![CDATA[Clickbait titles aside, this is a simple concept that I am having fun playing around with. But first let's rewind a bit... Contact Mic A contact mic is something you can clip onto an object and it senses vibrations from that object. In the video above I had it connected to a glass. The unmodified sound coming directly out the mic would sound something like this:]]></description><link>https://luvsheth.com/p/using-a-contact-mic-to-turn-any-object-into-a-musical-instrument</link><guid isPermaLink="false">https://luvsheth.com/p/using-a-contact-mic-to-turn-any-object-into-a-musical-instrument</guid><dc:creator><![CDATA[Luv Sheth]]></dc:creator><pubDate>Wed, 09 Dec 2020 13:44:36 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/h_600,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div id="vimeo-677675642" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677675642&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677675642?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><p>Clickbait titles aside, this is a simple concept that I am having fun playing around with. But first let's rewind a bit...</p><h1>Contact Mic</h1><p>A contact mic is something you can clip onto an object and it senses vibrations from that object. In the video above I had it connected to a glass. The unmodified sound coming directly out the mic would sound something like this:</p><div id="vimeo-677688191" class="vimeo-wrap" data-attrs="{&quot;videoId&quot;:&quot;677688191&quot;,&quot;videoKey&quot;:&quot;&quot;,&quot;belowTheFold&quot;:false}" data-component-name="VimeoToDOM"><div class="vimeo-inner"><iframe src="https://player.vimeo.com/video/677688191?autoplay=0" frameborder="0" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true"></iframe></div></div><h1>Synthesizer</h1><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!2TTB!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!2TTB!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 424w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 848w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 1272w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!2TTB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png" width="1024" height="718" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:718,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!2TTB!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 424w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 848w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 1272w, https://substackcdn.com/image/fetch/$s_!2TTB!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F98486cae-5b1f-47c8-a66f-9a13e2d11022_1024x718.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>A software synthesizer makes sounds depending on what "key" is being pressed. You can generally modify the tone and qualities of this sound over time in a lot of interesting ways. An example of what that might sound like if I played one note and held it is shown below:</p><div class="native-audio-embed" data-component-name="AudioPlaceholder" data-attrs="{&quot;label&quot;:null,&quot;mediaUploadId&quot;:&quot;eabf6486-16e4-4fe7-b84f-1eee3675ffbb&quot;,&quot;duration&quot;:10.083,&quot;downloadable&quot;:false,&quot;isEditorNode&quot;:true}"></div><h1>Putting them together</h1><p>I connected the mic to a glass and used chopsticks to hit the glass (just like in the video at the start of the article).</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TRD1!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TRD1!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TRD1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg" width="1024" height="768" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/f1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:768,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!TRD1!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 424w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 848w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!TRD1!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff1f6a019-bbf4-4f4f-aa47-240add5e93eb_1024x768.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">The keyboard in the image above is just being used as a table because my desk is too busy to get a nice pic on.</figcaption></figure></div><p>Let's call the sound coming out of the synth the "audio signal" and the sound coming out of the contact mic the "control signal". I made it so that the volume of the audio signal follows the volume of the control signal. The synth is constantly being played in the background, but how loud the signal from the contact mic is determines how loud the synth is playing.</p><p>But if we did just that, we would only have the same note playing again and again, just at different volumes.</p><div class="native-audio-embed" data-component-name="AudioPlaceholder" data-attrs="{&quot;label&quot;:null,&quot;mediaUploadId&quot;:&quot;616eeb36-0fd7-42df-9646-55a2dc8a644c&quot;,&quot;duration&quot;:4.179,&quot;downloadable&quot;:false,&quot;isEditorNode&quot;:true}"></div><p>It would be good to modify the pitch of the sound. Most commonly this is done by just playing a different key on your keyboard, but most synths also have a pitch modifier control.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!jN0_!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!jN0_!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 424w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 848w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 1272w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!jN0_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png" width="1024" height="719" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/ce556533-2d27-4283-9802-1020b282b283_1024x719.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:719,&quot;width&quot;:1024,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!jN0_!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 424w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 848w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 1272w, https://substackcdn.com/image/fetch/$s_!jN0_!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Fce556533-2d27-4283-9802-1020b282b283_1024x719.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Again, I can take the amplitude of the control signal and this time make it modify the pitch. The problem is the amplitude isn't something I can control very well because that would mean I have to hit the glass with extreme precision. If I just use the amplitude to control the pitch (with the volume constantly at 100% just to make the pitch modifying effect easier to discern), it sounds something this:</p><div class="native-audio-embed" data-component-name="AudioPlaceholder" data-attrs="{&quot;label&quot;:null,&quot;mediaUploadId&quot;:&quot;f4c688ed-110f-4385-9e67-92e087a7d012&quot;,&quot;duration&quot;:14.132,&quot;downloadable&quot;:false,&quot;isEditorNode&quot;:true}"></div><p>And the exact pitch changes look like this:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!u-vt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!u-vt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 424w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 848w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 1272w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!u-vt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png" width="617" height="90" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/92285480-149e-448f-8029-6f73b323d79c_617x90.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:90,&quot;width&quot;:617,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!u-vt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 424w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 848w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 1272w, https://substackcdn.com/image/fetch/$s_!u-vt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F92285480-149e-448f-8029-6f73b323d79c_617x90.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>I'd say it actually sounds okay and sort of interesting, but because the pitch changes are all over the place, you would have a hard time playing other melodic instruments like guitars or pianos with it because it's not following any particular key.</p><p>Instead, when controlling the pitch of the synth, I discretized the output so that it would only apply the pitch modification at certain levels.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!G1yk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!G1yk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 424w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 848w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 1272w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!G1yk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png" width="557" height="480" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/854baec2-290c-4c98-a353-c3889d1a5964_557x480.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:480,&quot;width&quot;:557,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!G1yk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 424w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 848w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 1272w, https://substackcdn.com/image/fetch/$s_!G1yk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F854baec2-290c-4c98-a353-c3889d1a5964_557x480.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">If the volume of the control signal was below 40%, it would stay at the original pitch. If the volume was between 40% and 80%, it would go up 3 semi-tones. If the volume was above 80%, it would go up 5 semi-tones.</figcaption></figure></div><p>This is what that sounds like:</p><div class="native-audio-embed" data-component-name="AudioPlaceholder" data-attrs="{&quot;label&quot;:null,&quot;mediaUploadId&quot;:&quot;2dfa1710-d350-46fe-8390-ea45301cfdc8&quot;,&quot;duration&quot;:18.991,&quot;downloadable&quot;:false,&quot;isEditorNode&quot;:true}"></div><p>And this is what the exact pitch changes look like:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1yum!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1yum!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 424w, https://substackcdn.com/image/fetch/$s_!1yum!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 848w, https://substackcdn.com/image/fetch/$s_!1yum!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 1272w, https://substackcdn.com/image/fetch/$s_!1yum!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1yum!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png" width="611" height="147" data-attrs="{&quot;src&quot;:&quot;https://bucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com/public/images/36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:147,&quot;width&quot;:611,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:null,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:null,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="https://substackcdn.com/image/fetch/$s_!1yum!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 424w, https://substackcdn.com/image/fetch/$s_!1yum!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 848w, https://substackcdn.com/image/fetch/$s_!1yum!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 1272w, https://substackcdn.com/image/fetch/$s_!1yum!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F36066a35-cdd1-4bec-bf27-64b8e2629576_611x147.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p>Next step is to turn on both volume and pitch control, which sounds like this:</p><div class="native-audio-embed" data-component-name="AudioPlaceholder" data-attrs="{&quot;label&quot;:null,&quot;mediaUploadId&quot;:&quot;20c0b9dc-2ff1-4d07-bde6-b25161ed7765&quot;,&quot;duration&quot;:18.155,&quot;downloadable&quot;:false,&quot;isEditorNode&quot;:true}"></div><p>To be honest the previous audio of discretized pitch with constant volume sounds better to me, but I think this is really cool and has some interesting potential.</p><h1>Conclusion</h1><p>This is a pretty limited set-up: the volume of the hit controls both the pitch and the volume of the output. Regardless, it was still fun to play with.</p><p>There is a really interesting way this might (should!) be extended:</p><p>The signal coming in from the contact mic is an audio signal. That means apart from volume, it also contains pitch/frequency information. Right now we only use the volume to control other variables in this system, but also using the pitch information would make this much more interesting and flexible as a way of making music. Additionally right now we are just controlling the pitch and volume of the synthesizer: but controlling some other parameters like the filters could also be quite fun!</p><p>P.S. I've seen similar stuff done with capacative sensors too but I thought a contact mic would be worth exploring!</p><div id="youtube2-o4iTQ7lr2W0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;o4iTQ7lr2W0&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/o4iTQ7lr2W0?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div id="youtube2-RPf28jaiU90" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;RPf28jaiU90&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/RPf28jaiU90?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div>]]></content:encoded></item></channel></rss>