{"id":678,"date":"2026-09-29T21:51:20","date_gmt":"2026-09-30T00:51:20","guid":{"rendered":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/2026\/09\/29\/ext-monitor-segunda-tela-hub-multimidia-rust\/"},"modified":"2026-09-29T21:51:20","modified_gmt":"2026-09-30T00:51:20","slug":"ext-monitor-segunda-tela-hub-multimidia-rust","status":"publish","type":"post","link":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/2026\/09\/29\/ext-monitor-segunda-tela-hub-multimidia-rust\/","title":{"rendered":"De um experimento de fim de semana a um hub multim\u00eddia completo: como criei o Ext-Monitor em Rust"},"content":{"rendered":"\n<p><strong>De um experimento de fim de semana a um hub multim\u00eddia completo: como criei o Ext-Monitor em Rust para transformar um microcomputador de US$ 10 em uma segunda tela de alta performance e central IoT.<\/strong><\/p>\n\n\n\n<p>Quem programa sabe como uma segunda tela faz falta na rotina di\u00e1ria de desenvolvimento. Mas os monitores port\u00e1teis dedicados costumam custar mais de R$ 1.500, ocupam espa\u00e7o na mochila e a grande maioria dos softwares de espelhamento para Linux sofre com lat\u00eancia no cursor do mouse, engasgos no Wayland e alto consumo de CPU.<\/p>\n\n\n\n<p>Comecei esse projeto despretensiosamente, por puro lazer e curiosidade t\u00e9cnica. Minha meta inicial era simples e pessoal: pegar uma plaquinha modesta que eu tinha na gaveta \u2014 um <strong>Raspberry Pi Zero W<\/strong> de dez d\u00f3lares \u2014 e tentar faz\u00ea-la funcionar como um monitor secund\u00e1rio que fosse \u00e1gil e realmente \u00fatil para a minha pr\u00f3pria bancada de trabalho.<\/p>\n\n\n\n<p>S\u00f3 que o projeto foi crescendo, os desafios de baixo n\u00edvel foram aparecendo e o que era para ser apenas uma tela estendida acabou virando um verdadeiro <strong>HUB DE SERVI\u00c7OS<\/strong> multim\u00eddia, combinando extens\u00e3o de v\u00eddeo, \u00e1udio digital HDMI, analisador de espectro em tempo real e central de m\u00eddia com fun\u00e7\u00e3o de Chromecast.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/portfolio\/03_bancada_dual_monitor.jpg\" alt=\"Bancada de Trabalho com o Ext-Monitor Operando em Dual Monitor\"\/><figcaption class=\"wp-element-caption\">Bancada real de testes: Raspberry Pi Zero W estendendo o desktop Wayland em monitor secund\u00e1rio via cabo \u00fanico USB<\/figcaption><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">\ud83c\udfaf O Desafio de Fazer Caber em um Sil\u00edcio de US$ 10<\/h2>\n\n\n\n<p>O chip Broadcom BCM2835 do Raspberry Pi Zero possui restri\u00e7\u00f5es severas de hardware:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n  <li><strong>1 \u00fanico n\u00facleo ARM1176 (ARMv6)<\/strong> operando a 1.0 GHz.<\/li>\n  <li><strong>Apenas 512 MB de mem\u00f3ria RAM compartilhada<\/strong> entre o sistema e a GPU VideoCore IV.<\/li>\n  <li><strong>Controlador USB 2.0 integrado (<code>dwc2<\/code>)<\/strong> que divide interrup\u00e7\u00f5es com o sistema operacional.<\/li>\n<\/ul>\n\n\n\n<p>Qualquer distribui\u00e7\u00e3o Linux comum com X11 ou Wayfire consome mais de 350 MB de RAM s\u00f3 no boot e trava o processador em 100%. Para viabilizar uma taxa est\u00e1vel de 30 a 60 FPS com <strong>menos de 0.8% de uso de CPU<\/strong>, descartei bibliotecas pesadas e desenhei uma arquitetura em <strong>Rust nativo<\/strong> direto no sil\u00edcio.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/portfolio\/04_hardware_raspberry_pi_zero.jpg\" alt=\"Placa Raspberry Pi Zero com conex\u00f5es USB e HDMI\"\/><figcaption class=\"wp-element-caption\">Conex\u00e3o f\u00edsica anti-erro: alimenta\u00e7\u00e3o e dados no conector Micro-USB OTG central e sa\u00edda digital mini-HDMI<\/figcaption><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udee0\ufe0f A Arquitetura em Cinco Pilares<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1. Scanout Zero-Copy no DRM\/KMS &#038; DMA-BUF<\/h3>\n\n\n<p>No receptor, <strong>n\u00e3o existe servidor gr\u00e1fico X11 nem Wayland<\/strong>. O decodificador H.264 V4L2 M2M da GPU VideoCore IV (<code>\/dev\/video10<\/code>) decodifica os quadros e os importa diretamente como descritores de mem\u00f3ria <strong>DMA-BUF<\/strong> para o driver <strong>DRM\/KMS<\/strong> (<code>\/dev\/dri\/card0<\/code>). A imagem \u00e9 projetada no plano prim\u00e1rio do HDMI sem nenhuma convers\u00e3o de cores na CPU ARM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2. Modo USB Bulk Direct com Lat\u00eancia Sub-Milissegundo (&lt; 1 ms)<\/h3>\n\n\n<p>Atrav\u00e9s de um driver USB Gadget customizado (FunctionFS classe <code>0xFF<\/code>), v\u00eddeo e comandos viajam a 480 Mbps brutos atrav\u00e9s de um \u00fanico cabo micro-USB comum. O canal contorna completamente a pilha de rede TCP\/IP, atingindo lat\u00eancia inferior a 1 milissegundo, imune a interfer\u00eancias de Wi-Fi e bloqueios de firewall.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3. \u00c1udio Digital HDMI Integrado ao PipeWire<\/h3>\n\n\n<p>O computador host cria um sink virtual no PipeWire (<code>Raspberry_Pi_HDMI_Audio<\/code>), capturando PCM est\u00e9reo a 48 kHz e transmitindo via codec Opus de baixa lat\u00eancia (UDP 5004). O som \u00e9 decodificado e reproduzido diretamente pelas caixas da TV ou monitor atrav\u00e9s do conector HDMI.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4. Analisador de Espectro FFT de 512 Pontos em Tempo Real<\/h3>\n\n\n<p>Quando o streaming de v\u00eddeo da \u00e1rea de trabalho \u00e9 pausado e h\u00e1 m\u00fasica tocando, um motor matem\u00e1tico de <strong>FFT Cooley-Tukey com janela de Hann<\/strong> calcula a energia de 24 bandas logar\u00edtmicas de frequ\u00eancia. Um multiplexador de hardware chaveia a sa\u00edda HDMI para exibir um visualizador din\u00e2mico e responsivo a 30 FPS na TV (evitando que a tela fique apagada) e espelha o resultado no painel Web em Canvas.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/portfolio\/01_dashboard_web_visualizer.png\" alt=\"Painel Web com Visualizador de \u00c1udio Realtime Canvas\"\/><figcaption class=\"wp-element-caption\">Web Dashboard v2.3.0: controle de bitrate, telemetria em tempo real e visualizador de espectro FFT em Canvas 30 FPS<\/figcaption><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">5. Central de M\u00eddia IoT &#038; 100% de Execu\u00e7\u00e3o em RAM<\/h3>\n\n\n<p>O appliance incorpora um receptor UPnP\/DLNA (estilo Chromecast), permitindo tocar arquivos de m\u00eddia da rede dom\u00e9stica direto na tela. Todo o sistema operacional roda descompactado na mem\u00f3ria RAM em um <code>initramfs<\/code> minimalista de apenas 32 MB constru\u00eddo com Buildroot e Musl libc. O cart\u00e3o micro-SD \u00e9 desvinculado ap\u00f3s o boot, eliminando qualquer risco de desgaste ou corrup\u00e7\u00e3o ao puxar o cabo da tomada.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/portfolio\/02_splash_quadrilingue_hdmi.png\" alt=\"Splash Screen Quadril\u00edngue do Ext-Monitor na TV\"\/><figcaption class=\"wp-element-caption\">Tela de boas-vindas quadril\u00edngue com QR Code din\u00e2mico, telemetria de rede e leitura VESA EDID do monitor<\/figcaption><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udcca Comparativo T\u00e9cnico de Bancada<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Solu\u00e7\u00e3o<\/th><th>Taxa de Quadros<\/th><th>Lat\u00eancia<\/th><th>Uso de CPU no Pi Zero<\/th><th>Estabilidade<\/th><\/tr><\/thead><tbody><tr><td><strong>GUD USB Display (Legado)<\/strong><\/td><td>5\u201312 FPS<\/td><td>&gt; 250 ms<\/td><td><strong>100% (gargalo)<\/strong><\/td><td>Tearing severo<\/td><\/tr><tr><td><strong>VNC \/ RDP Mirror<\/strong><\/td><td>15\u201325 FPS<\/td><td>80\u2013150 ms<\/td><td><strong>75\u201390%<\/strong><\/td><td>Artefatos de bloco<\/td><\/tr><tr><td><strong>Ext-Monitor (Rust + VideoCore IV)<\/strong><\/td><td><strong>30\u201360 FPS<\/strong><\/td><td><strong>&lt; 1 ms (Bulk) \/ &lt; 15 ms (UDP)<\/strong><\/td><td><strong>~0.8%<\/strong><\/td><td><strong>Zero Tearing \/ Fluido<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83c\udf81 C\u00f3digo Aberto e Documenta\u00e7\u00e3o T\u00e9cnica (Licen\u00e7a MIT)<\/h2>\n\n\n\n<p>Fiz esse projeto para resolver uma necessidade da minha bancada, me diverti demais enfrentando os limites do sil\u00edcio e decidi disponibilizar a solu\u00e7\u00e3o completa em c\u00f3digo aberto com <strong>licen\u00e7a MIT<\/strong> para quem quiser montar o seu monitor secund\u00e1rio ou central IoT:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n  <li>\ud83d\udd17 <strong>Reposit\u00f3rio Oficial no GitHub:<\/strong> <a href=\"https:\/\/github.com\/programandosolucoes\/ext-monitor\" target=\"_blank\" rel=\"noopener\">github.com\/programandosolucoes\/ext-monitor<\/a><\/li>\n  <li>\ud83d\udce6 <strong>Release v2.3.0 Final Congelada:<\/strong> <a href=\"https:\/\/github.com\/programandosolucoes\/ext-monitor\/releases\/tag\/v2.3.0-final\" target=\"_blank\" rel=\"noopener\">v2.3.0-final<\/a><\/li>\n  <li>\ud83d\udcd6 <strong>O Livro do Ext-Monitor (20 Blueprints):<\/strong> <a href=\"https:\/\/github.com\/programandosolucoes\/ext-monitor\/blob\/main\/docs\/LIVRO-EXT-MONITOR.md\" target=\"_blank\" rel=\"noopener\">LIVRO-EXT-MONITOR.md<\/a><\/li>\n  <li>\ud83d\udcd8 <strong>Manual de Opera\u00e7\u00e3o Completo (Ingl\u00eas):<\/strong> <a href=\"https:\/\/github.com\/programandosolucoes\/ext-monitor\/blob\/main\/docs\/OPERATION-MANUAL.md\" target=\"_blank\" rel=\"noopener\">OPERATION-MANUAL.md<\/a><\/li>\n<\/ul>\n\n\n\n<p>Se voc\u00ea tiver um Raspberry Pi Zero na gaveta ou estiver procurando uma segunda tela \u00e1gil e gratuita para o seu Linux ou Windows, teste o projeto e compartilhe suas impress\u00f5es!<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>De um experimento de fim de semana a um hub multim\u00eddia completo: como criei o Ext-Monitor em Rust para transformar um microcomputador de US$ 10 em uma segunda tela de alta performance e central IoT. Quem programa sabe como uma segunda tela faz falta na rotina di\u00e1ria de desenvolvimento. Mas os monitores port\u00e1teis dedicados costumam [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[144,142,143,131,138,141,140,136,137,139],"class_list":["post-678","post","type-post","status-publish","format-standard","hentry","category-sem-categoria","tag-drm","tag-embedded","tag-hardware","tag-iot","tag-linux","tag-opensource","tag-pipewire","tag-raspberrypi","tag-rust","tag-wayland"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"en","enabled_languages":["en","br","it"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"br":{"title":false,"content":false,"excerpt":false},"it":{"title":false,"content":false,"excerpt":false}}},"_links":{"self":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/posts\/678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/comments?post=678"}],"version-history":[{"count":0,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/posts\/678\/revisions"}],"wp:attachment":[{"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/media?parent=678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/categories?post=678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/carloslopes.programandosolucoes.com.br\/index.php\/wp-json\/wp\/v2\/tags?post=678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}