Voltar ao catálogo
Season 46 7 Episódios 27 min 2026

MicroPython

Edição de 2026. Um guia abrangente sobre MicroPython para microcontroladores. Aprenda a executar um interpretador Python 3 completo em hardware bare-metal.

Sistemas Embebidos Microcontroladores Python Core
MicroPython
A Reproduzir
Click play to start
0:00
0:00
1
O Python que cabe em 256K
Descubra como o MicroPython comprime um interpretador Python 3 completo em microcontroladores bare-metal. Exploramos a sua identidade central, as suas diferenças em relação ao CPython e como consegue ser executado em ambientes altamente restritos.
3m 55s
2
A ponte de hardware: O módulo machine
Aprenda a controlar periféricos de microcontroladores diretamente a partir do Python. Mergulhamos no módulo machine, explorando como interagir com Pins, PWM e memória raw.
4m 05s
3
Live Coding no MCU: REPL e mpremote
Revolucione o seu fluxo de trabalho de desenvolvimento embedded. Abordamos o REPL do MicroPython e a ferramenta de linha de comandos mpremote para automatizar ligações série e execução em tempo real.
3m 49s
4
Três linhas para o WiFi: O módulo network
Transforme um microcontrolador num nó IoT ligado. Exploramos o módulo network, detalhando como ligar ao WiFi como station ou alojar o seu próprio Access Point.
3m 48s
5
Sobreviver às restrições: RAM e o GC
Domine a arte de escrever código Python eficiente em termos de memória. Discutimos a fragmentação da heap, a pré-alocação de buffers e a garbage collection manual para manter o seu microcontrolador a funcionar sem problemas.
3m 48s
6
Compilado vs. Frozen: Implementação em produção
Aprenda a implementar aplicações massivas sem ficar sem RAM. Exploramos ficheiros .mpy pré-compilados e o freezing de bytecode diretamente para a memória flash do microcontrolador.
3m 56s
7
Determinismo em Python: Timers e Interrupts
Alcance um comportamento em tempo real no MicroPython utilizando timers de hardware e interrupt service routines. Abordamos as regras estritas para escrever ISRs e evitar a alocação de memória.
3m 53s

Episódios

1

O Python que cabe em 256K

3m 55s

Descubra como o MicroPython comprime um interpretador Python 3 completo em microcontroladores bare-metal. Exploramos a sua identidade central, as suas diferenças em relação ao CPython e como consegue ser executado em ambientes altamente restritos.

Download
Olá, daqui é o Alex do DEV STORIES DOT EU. MicroPython, episódio 1 de 7. O Python de desktop normalmente consome megabytes de memória só para arrancar. Tenta pôr isso num chip minúsculo de dois dólares e o sistema fica imediatamente sem recursos. Para escreveres Python para microcontroladores, precisas de um interpretador que caiba numa fração desse espaço sem perder as core features da linguagem em que confias. É exatamente isso que o MicroPython oferece. O MicroPython é uma implementação leve e altamente eficiente da linguagem de programação Python 3. Foi desenhado especificamente para correr em ambientes com recursos limitados. O Python standard, muitas vezes chamado de CPython, assume que está a correr em cima de um sistema operativo completo como o Linux ou o Windows, com gigabytes de storage e bastante RAM. O MicroPython inverte esta premissa. Foi construído para correr em bare metal. Não há um sistema operativo subjacente a gerir o hardware. Em vez disso, o MicroPython atua como o sistema operativo. Interage diretamente com o hardware para que possas escrever scripts de alto nível para controlar dispositivos físicos. A engenharia por trás disto foca-se inteiramente em restrições severas de recursos. O MicroPython consegue correr totalmente em apenas 256 kilobytes de espaço de código compilado. Ainda mais impressionante, requer apenas 16 kilobytes de RAM para funcionar. Dentro destes limites apertados, oferece um ambiente Python totalmente funcional. O Python standard inclui uma standard library enorme, famosa pela abordagem batteries included. O MicroPython reduz isso a um subset de módulos cuidadosamente escolhido, mantendo apenas o que faz sentido para um sistema embedded. Apesar destas otimizações pesadas, a linguagem em si continua a ser Python 3 autêntico. Isto significa que o código que escreves no teu desktop traduz-se diretamente para o dispositivo embedded. O MicroPython suporta features avançadas da linguagem, como closures, list comprehensions, generators e standard exception handling. Até lida com inteiros de precisão arbitrária. Se a tua lógica exigir multiplicar números enormes, o MicroPython escala a memória dinamicamente para te dar a resposta correta sem bater num limite arquitetónico rígido, exatamente como o Python de desktop. Aqui está o ponto chave. Como todo o engine de Python cabe no chip, tens um prompt interativo live diretamente no hardware. Este read-eval-print loop muda a forma como escreves código embedded. Normalmente, programar um microcontrolador envolve escrever código em C, compilá-lo no teu desktop, fazer o flash para a board e esperar que corra. Com o MicroPython, ligas a board ao teu computador, abres um terminal serial e digitas comandos Python diretamente no chip. Podes testar a lógica, ler valores de sensores ou fazer trigger de ações instantaneamente. Para tornar isto possível, o MicroPython inclui módulos built-in específicos que vão além do Python standard. Como o Python standard não sabe nada sobre a leitura de pinos físicos ou a configuração de hardware timers, o MicroPython fornece interfaces especializadas e altamente otimizadas para estas tarefas. Estas estão integradas diretamente no firmware do teu chip específico, dando-te raw control sobre o mundo físico sem aumentar o memory footprint. Ao remover o sistema operativo e encolher o interpretador para caber em 256 kilobytes, o MicroPython transforma hardware barato e com poucos recursos num ambiente de desenvolvimento dinâmico e interativo. Se quiseres apoiar o podcast, podes encontrar-nos pesquisando por DevStoriesEU no Patreon. Obrigado por ouvires. Até à próxima!
2

A ponte de hardware: O módulo machine

4m 05s

Aprenda a controlar periféricos de microcontroladores diretamente a partir do Python. Mergulhamos no módulo machine, explorando como interagir com Pins, PWM e memória raw.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. MicroPython, episódio 2 de 7. Para de recompilar código C e de fazer flash ao firmware só para testar um sensor ou acionar um interruptor. Tu queres controlo direto sobre o teu microcontrolador sem o boilerplate, e é exatamente isso que o módulo machine oferece. O módulo machine é a tua ponte de hardware. Ele traduz código Python nos sinais elétricos que controlam os pinos físicos da tua board. Fornece acesso a funcionalidades centrais de hardware, como a frequência da unidade central de processamento, sleep modes, e input e output digital. Mas, como está tão próximo do metal, vem com um aviso. Este módulo não te leva pela mão. Se configurares o registo de hardware errado ou escreveres num endereço de memória protegido, a tua board vai fazer crash e reboot. A base deste módulo é a class Pin. Um pino é uma ligação física no microcontrolador que pode enviar ou receber tensões elétricas. Para controlares um componente básico como um LED, precisas de enviar tensão para um pino específico. Fazes isso importando o módulo machine e criando um objeto Pin. Forneces o número do pino físico e defines se o pino deve atuar como input ou output. Para um LED, configuras o pino como output passando uma constante de output. Assim que o objeto é criado, usas esse objeto para definir o state. Aplicar o valor um coloca a linha de hardware em high e liga o LED. Aplicar o valor zero coloca-a em low e desliga o LED. Estás a manipular o state digital do hardware em tempo real a partir de um prompt de Python. Às vezes, os states básicos de on e off não são suficientes. Se quiseres atenuar esse LED ou controlar a velocidade de um motor, precisas de Pulse Width Modulation, ou PWM. O módulo machine tem uma class PWM dedicada para isto. Em vez de um fluxo constante de tensão, o PWM liga e desliga o pino de forma extremamente rápida. Crias um objeto PWM passando-lhe o objeto Pin que já configuraste. A seguir, defines dois parâmetros de hardware: frequency e duty cycle. Aqui está a ideia principal. A frequency dita quantas vezes por segundo o sinal completa um ciclo, enquanto o duty cycle dita que percentagem desse tempo o sinal está efetivamente em on. Se definires o duty cycle para cinquenta por cento, o LED só recebe energia metade do tempo, fazendo com que pareça ter metade do brilho para o olho humano. Ao alterares gradualmente esse valor de duty cycle dentro de um loop, instruis o hardware a criar um efeito de fading suave. Para use cases avançados, o módulo machine oferece acesso direto aos registos de hardware subjacentes através de objetos chamados mem8, mem16 e mem32. Estes permitem-te ler e escrever raw bytes, half-words ou words de 32 bits diretamente em endereços de memória específicos. Não usas um objeto Pin para isto. Usas a notação padrão de parênteses retos, passando o endereço de memória física a que queres aceder, exatamente como se estivesses a procurar uma key num dictionary. Atribuir um valor a um endereço mem32 faz overwrite instantaneamente a esse registo de hardware. É assim que interages com features obscuras do microcontrolador que o MicroPython ainda não fez wrap explicitamente numa class. Isto dá-te autoridade absoluta sobre o silício. O verdadeiro poder do módulo machine não é apenas tornar o hardware acessível, mas sim remover completamente a barreira entre escrever lógica de software de alto nível e manipular voltagem física. Obrigado por ouvirem. Fiquem bem, pessoal.
3

Live Coding no MCU: REPL e mpremote

3m 49s

Revolucione o seu fluxo de trabalho de desenvolvimento embedded. Abordamos o REPL do MicroPython e a ferramenta de linha de comandos mpremote para automatizar ligações série e execução em tempo real.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. MicroPython, episódio 3 de 7. Esquece o ciclo aborrecido de compile, flash e reboot. Num projeto embedded típico, alteras uma variável, esperas minutos por um build, escreves na memória flash e esperas que funcione. O MicroPython contorna isto completamente, permitindo-te falar diretamente com o chip em tempo real. Este episódio aborda o Live Coding do MCU usando o REPL e o mpremote. O REPL significa Read-Eval-Print Loop. É um prompt interativo a correr diretamente no teu microcontrolador. Ligas a tua placa por USB, abres um terminal série, escreves código Python, e o chip executa-o instantaneamente. O REPL standard foi desenhado para humanos. Oferece auto-indentation, histórico de comandos e auto-completion básico. É perfeito para testar um toggle rápido de um pino de hardware. No entanto, existe um segundo modo chamado raw REPL. As pessoas costumam confundir isto com uma versão limitada do MicroPython, mas na verdade é apenas um modo de input diferente, ativado ao enviar um caráter de controlo específico por porta série. O raw REPL desativa o echo de carateres e a auto-indentation. As tools usam o raw REPL para injetar programaticamente grandes blocos de código no microcontrolador. Se um script tentasse colar texto no REPL standard, a auto-indentation pensada para humanos entraria em cascata e iria estragar completamente a formatação do Python. O raw REPL garante que o código entra exatamente como foi escrito. Isto leva-nos ao mpremote. Esta é a command-line tool oficial para interagir com dispositivos MicroPython, e controla o raw REPL under the hood para fazer o trabalho pesado. Para live coding, o mpremote oferece dois comandos poderosos: run e mount. Usas o comando run para executar um script local do teu computador diretamente na placa. Escreves o teu código no teu editor de texto favorito, abres o terminal e invocas mpremote run seguido do nome do teu ficheiro. Aqui está o ponto chave. O código é enviado pela linha série e executado inteiramente na RAM do microcontrolador. Nunca é escrito na memória flash do dispositivo. Se escreveres um mau loop e provocares um crash na placa, basta fazeres um hard reset ao chip. A flash permanece intacta, poupando write cycles, e o teu development loop demora apenas segundos. Quando o teu projeto cresce para lá de um único script, usas o comando mount. Este comando diz ao mpremote para pegar num diretório local no teu PC e mapeá-lo através da ligação série. O microcontrolador faz um override temporário ao seu próprio storage e trata essa pasta no teu computador como se fosse o seu filesystem interno. Considera um cenário em que estás a escrever um driver de ecrã complexo. Normalmente, terias de copiar o ficheiro do driver para a placa, correr o teu script principal, observar um glitch no ecrã, editar o ficheiro no teu PC, e copiá-lo de novo. Com o comando mount, o microcontrolador executa o driver diretamente do storage do teu PC. Guardas o ficheiro no teu editor de texto no teu laptop, reinicias o script na placa, e as alterações são aplicadas imediatamente. Iteras tão rápido quanto consegues escrever, eliminando completamente o passo de flashing do teu workflow. O verdadeiro poder do MicroPython não está apenas na sintaxe de Python em si, mas em como tools como o mpremote apagam a fronteira entre o teu development environment local e o hardware embedded físico. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
4

Três linhas para o WiFi: O módulo network

3m 48s

Transforme um microcontrolador num nó IoT ligado. Exploramos o módulo network, detalhando como ligar ao WiFi como station ou alojar o seu próprio Access Point.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. MicroPython, episódio 4 de 7. Ligar um microcontrolador básico a uma rede Wi-Fi usando código C tradicional geralmente exige centenas de linhas de boilerplate apenas para inicializar o rádio e tratar do handshake. É um processo aborrecido e propenso a erros. Em MicroPython, podes estabelecer uma ligação wireless em literalmente três linhas. Esse é o trabalho do módulo network, especificamente da classe WLAN. O módulo network abstrai as interfaces de rede do hardware subjacente. Para operações Wi-Fi, dependes da classe network dot WLAN. Um chip Wi-Fi standard pode operar em dois papéis distintos. Tens de definir explicitamente qual o papel que queres quando crias o objeto WLAN. O primeiro papel é o Station mode, especificado usando a constante STA underscore IF. Usas o Station mode quando o teu hardware precisa de se ligar como cliente a um router upstream, tal como um smartphone que se liga a uma rede doméstica. O segundo papel é o Access Point mode, especificado usando AP underscore IF. Neste modo, o próprio microcontrolador atua como um router, transmitindo a sua própria rede wireless para que dispositivos externos se possam ligar diretamente a ele. O Access Point mode é incrivelmente útil ao fazer o deploy de hardware em locais remotos onde não existe nenhuma rede externa, permitindo que te ligues localmente para configuração. Colocar a tua board online requer uma sequência específica. Primeiro, crias o objeto WLAN usando a constante do Station mode. Por defeito, o rádio Wi-Fi físico está desligado para poupar energia. Tens de o ligar passando True para o método active no teu objeto WLAN. Assim que a interface estiver ativa, invocas o método connect com o nome e a password da tua rede wireless. Aqui está o ponto chave. O método connect é estritamente non-blocking. Quando o invocas, o MicroPython entrega as credenciais ao processador de rede e continua imediatamente a executar o teu script. Ele deliberadamente não espera que a autenticação de rede termine. Este design permite que a tua aplicação principal atualize um display ou leia um sensor enquanto o rádio negocia com o router em background. No entanto, se o teu código tentar enviar dados imediatamente após chamar o connect, a operação vai fazer crash porque a board ainda não tem realmente uma ligação. Geres isto fazendo polling à interface. O objeto WLAN fornece um método chamado isconnected, que devolve um valor boolean simples. O padrão standard é escrever um while loop que avalia se isconnected é False. Dentro deste loop, introduzes um pequeno atraso, como fazer um sleep de meio segundo. A execução pausa aqui, verificando repetidamente o estado do hardware até que o router finalmente aceite a ligação e isconnected devolva True. Assim que o loop termina, o hardware está oficialmente online. Para verificar os detalhes da rede, chamas o método ifconfig no teu objeto WLAN. Este método faz output de uma coleção de quatro itens específicos: o endereço IP atribuído, a subnet mask, o gateway e o servidor DNS primário. Podes extrair o primeiro item desta coleção e imprimi-lo na consola para veres exatamente qual o endereço IP que o router concedeu à tua board. A natureza non-blocking do método connect significa que és sempre responsável por verificar o estado do hardware antes de tentares fazer route de dados pela rede. Por hoje é tudo. Obrigado por ouvires — vai construir algo incrível.
5

Sobreviver às restrições: RAM e o GC

3m 48s

Domine a arte de escrever código Python eficiente em termos de memória. Discutimos a fragmentação da heap, a pré-alocação de buffers e a garbage collection manual para manter o seu microcontrolador a funcionar sem problemas.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. MicroPython, episódio 5 de 7. O Python adora alocar memória dinamicamente, criando novos objetos para cada cálculo. Isso funciona perfeitamente num servidor, mas num microcontrolador, esse hábito vai acabar por fazer crashar a tua board, deixando-te a olhar para um memory error mesmo quando aparentemente ainda tens RAM livre. Hoje vamos focar-nos em sobreviver às restrições: RAM e o GC. A memória onde os teus objetos Python vivem chama-se heap. No MicroPython, o heap é incrivelmente pequeno. Quando crias objetos, eles ocupam blocos de espaço. Quando esses objetos já não são precisos, são limpos. Isto deixa buracos na tua memória. Com o tempo, à medida que objetos de vários tamanhos são criados e destruídos, o teu heap fica a parecer um queijo suíço. Isto é heap fragmentation. Aqui está o ponto chave. Quando precisas de alocar um novo objeto, o MicroPython precisa de um único bloco contíguo de memória para o encaixar. Se o teu heap estiver muito fragmentado, podes ter vinte kilobytes de RAM livre no total, mas nenhum buraco maior do que um kilobyte. Se pedires dois kilobytes, o teu programa crasha. Tens de parar de desperdiçar RAM, a começar pelas tuas global variables. Se tens valores inteiros que nunca mudam, como números de pinos ou hardware addresses, não lhes faças assign normalmente. O MicroPython fornece uma declaração especial chamada const. Se envolveres o teu inteiro nesta declaração const, o compiler substitui o nome da variável pelo próprio número em todo o teu código durante a compilação. Isto evita totalmente que uma variável seja criada na RAM. A seguir, olha para os teus loops. A criação dinâmica de objetos dentro de um loop rápido é a principal causa de fragmentação. Estás a ler um sensor num SPI bus cem vezes por segundo. Se usares um comando read standard, o MicroPython cria uma sequência de bytes completamente nova na memória para cada leitura. Esses objetos acumulam-se rapidamente, preenchendo os buracos e destruindo o teu espaço contíguo. Em vez de criares novos objetos, reutiliza os que já tens. Antes do teu loop começar, cria um bytearray com o tamanho correto. Um bytearray é um bloco de memória mutável. Depois, dentro do teu loop, usa um hardware method chamado readinto. Passas o teu bytearray pré-existente para o readinto. O hardware despeja os dados do sensor diretamente nesse mesmo bloco de memória, a fazer overwrite aos dados antigos. Processas os dados, o loop repete-se, e zero memória nova é alocada. Mesmo com código cuidadoso, a criação de alguns objetos é inevitável, o que nos leva ao Garbage Collector. Por default, o Garbage Collector corre automaticamente quando a alocação de memória falha. Ele faz um scan por objetos não utilizados e liberta o seu espaço. No entanto, este processo leva tempo. Se for acionado automaticamente durante uma operação sensível ao tempo, o teu código vai pausar de forma imprevisível. Para resolver isto, tu assumes o controlo. Chama a função collect do módulo gc explicitamente. Encontra um ponto seguro no teu código, como o final do teu main loop, e aciona a collection aí. Isto mantém o heap limpo de acordo com o teu schedule, evitando atrasos inesperados. No desktop Python, a memória é algo que a linguagem gere por ti, mas no MicroPython, a memória é um contentor físico que tens de empacotar à mão. É tudo por este episódio. Obrigado por ouvires, e continua a desenvolver!
6

Compilado vs. Frozen: Implementação em produção

3m 56s

Aprenda a implementar aplicações massivas sem ficar sem RAM. Exploramos ficheiros .mpy pré-compilados e o freezing de bytecode diretamente para a memória flash do microcontrolador.

Download
Olá, daqui é o Alex da DEV STORIES DOT EU. MicroPython, episódio 6 de 7. Fazes o upload de um ficheiro Python perfeitamente válido para o teu microcontrolador, escreves import, e a board crasha instantaneamente com um erro de out-of-memory. O código em si está bom, mas o processo de o carregar consumiu toda a tua memória disponível. Resolver isto exige contornar o compiler no dispositivo, o que nos leva a código compilado versus código frozen para deployments em produção. Quando corres um script Python standard num desktop, a memória é praticamente infinita. Num microcontrolador, a memória é estritamente limitada. Quando colocas um source file Python standard no teu dispositivo e corres o comando import, o MicroPython não lê apenas o ficheiro. O compiler arranca logo ali no microcontrolador. Ele faz o parse do texto, constrói uma abstract syntax tree e gera bytecode. Cada um desses passos aloca memória na RAM. Imagina uma grande framework de IoT que lida com networking, segurança e dados de sensores. Se tentares fazer o import deste módulo enorme a partir de um source file standard, o compiler provavelmente vai esgotar a memória heap disponível antes sequer da primeira linha da tua aplicação ser executada. O pico no uso de RAM durante a fase de compilação mata o processo. Para contornar isto, precisas de remover o passo de compilação do microcontrolador. Fazes isto pré-compilando o teu código usando uma tool de desktop chamada cross-compiler, ou mpy-cross. Corres esta tool no teu computador principal. Ela processa o teu source file Python e faz o output de um ficheiro compilado com a extensão M-P-Y. Este ficheiro contém o bytecode pré-gerado. Quando transferes este ficheiro compilado para o microcontrolador e fazes o import, o MicroPython reconhece o formato e salta a fase de compilação por completo. Evitas totalmente o pico de memória causado pelo compiler. É aqui que a coisa fica interessante. Embora a pré-compilação te salve do pico de memória da compilação, o microcontrolador continua a carregar o bytecode do file system para a RAM para o executar. Se a tua framework de IoT for suficientemente grande, só o bytecode vai continuar a consumir demasiada RAM, deixando-te com muito pouco espaço para as variáveis e dados da tua aplicação. Quando os ficheiros pré-compilados não são suficientes, o passo final é fazer freezing ao bytecode. Fazer freezing significa embutir o código compilado diretamente no firmware do MicroPython. Em vez de copiares o ficheiro compilado para o file system da board, colocas o mesmo num diretório de modules específico dentro do source code do MicroPython no teu computador. A seguir, fazes o rebuild de toda a imagem de firmware do MicroPython do zero e fazes flash deste firmware customizado para a tua board. Isto muda exatamente a forma como o código é executado. Quando fazes o import de um módulo frozen, o MicroPython não copia o bytecode para a RAM de todo. Como o código está embutido no firmware, ele reside permanentemente na memória flash do microcontrolador. O MicroPython executa o bytecode diretamente da flash. Ao executar a partir da flash, o footprint de RAM de fazer o import dessa framework de IoT massiva cai para quase zero. Toda a tua RAM permanece totalmente livre para processar dados em tempo real. A diferença fundamental resume-se a onde o teu código vive enquanto corre. A pré-compilação poupa memória durante o passo de import, mas o freezing poupa memória durante toda a vida do programa ao forçar a execução a acontecer inteiramente na memória flash. Se quiseres ajudar a apoiar o programa, podes procurar por DevStoriesEU no Patreon. É tudo por hoje. Obrigado por ouvires, e continua a desenvolver!
7

Determinismo em Python: Timers e Interrupts

3m 53s

Alcance um comportamento em tempo real no MicroPython utilizando timers de hardware e interrupt service routines. Abordamos as regras estritas para escrever ISRs e evitar a alocação de memória.

Download
Olá, daqui fala o Alex da DEV STORIES DOT EU. MicroPython, episódio 7 de 7. Escrever uma interrupt service routine de hardware numa linguagem de alto nível com garbage collection parece estar a pedir um crash imediato do sistema. Mas o MicroPython na verdade permite-o, desde que obedeças a uma regra inquebrável: zero alocação de memória. Este episódio aborda o Determinismo em Python: Timers e Interrupts. Quando precisas de ler um sensor exatamente mil vezes por segundo, um loop standard com uma função sleep vai falhar. O garbage collection e as background tasks introduzem atrasos aleatórios, destruindo o teu timing. Para obteres um comportamento determinístico, precisas de um timer de hardware. Usando o módulo machine, configuras um objeto Timer para disparar periodicamente e executar uma função de callback específica. Este callback é a tua Interrupt Service Routine, ou ISR. Os timers disparam soft ou hard interrupts. Um soft interrupt é agendado pela virtual machine do MicroPython quando é seguro fazê-lo. Escreves uma soft ISR exatamente como código Python normal. Pode criar objetos, fazer append a listas e lidar com números floating-point. A desvantagem é a latência. Se o garbage collector estiver a correr quando o timer disparar, o teu soft interrupt simplesmente fica à espera na fila. Se precisas de uma precisão de timing rigorosa, configuras o timer para disparar um hard interrupt. Um hard interrupt para o processador imediatamente. Faz bypass à virtual machine e corre o teu callback instantaneamente. Aqui está o ponto chave. Como um hard interrupt faz preempt ao estado atual do sistema, pode interromper o próprio memory manager. Se a tua ISR tentar alocar memória no heap enquanto o heap está a meio de ser modificado, o microcontrolador vai crashar. Esta restrição dita exatamente como escreves hard ISRs. Não podes alocar nenhuma memória. Nada de criar listas. Nada de construir dicionários. Nada de manipulação de strings. Até mesmo matemática floating-point é estritamente proibida, porque em Python, cada float é um objeto recém-alocado no heap. O teu código tem de executar rápido, depender de matemática de inteiros e usar estruturas de memória pré-existentes. Considera um cenário onde um timer de hardware dispara a 1000 Hertz. A cada milissegundo, a hard ISR lê o valor de um sensor. Como não podes fazer append da leitura a uma lista, tens de pré-alocar o teu storage antes de iniciar o timer. Crias um bytearray de mil bytes no teu programa principal. Também defines uma variável de index global. Quando o timer dispara, a ISR lê o sensor. Atualiza o index global, guarda o inteiro raw no bytearray nessa posição e sai. O espaço de memória foi reservado inteiramente à partida. O interrupt apenas o atualiza in place, garantindo uma execução sem jitter. Assim que o buffer estiver cheio, a ISR precisa de passar os dados para o programa principal. Não podes acionar uma função complexa de processamento de dados diretamente a partir da hard ISR. Em vez disso, usas o micropython dot schedule. Esta função recebe uma referência para um callback e coloca-o na queue para correr assim que o sistema regressar a um estado de execução soft e seguro. Lidar com hardware interrupts força-te a parar de pensar no Python como uma resource pool infinita e a começar a monitorizar exatamente quando e onde a tua memória é alocada. Consulta a documentação oficial do MicroPython para veres os comportamentos específicos de interrupts do teu hardware port, e tenta quebrar intencionalmente as regras de memória na tua própria board para veres como o sistema reage. Se quiseres sugerir tópicos para a nossa próxima série, passa por devstories dot eu. Gostaria de tirar um momento para te agradecer por ouvires — ajuda-nos imenso. Fica bem!