Sebenta · Desenvolver e executar sistemas baseados em microcontrolador (UC00671)
- Introdução
- 1. Arquitetura de um microcontrolador
- 2. Ferramentas de desenvolvimento e critérios de seleção
- 3. Conversores A/D e D/A
- 4. Linguagem C/C++ para microcontroladores
- 5. Entradas digitais e analógicas
- 6. Saídas: LEDs, displays, motores e relés
- 7. Comunicação série: UART, SPI e I2C
- 8. Interrupções
- 9. Sensores, atuadores e controlo dinâmico
- 10. Interface de utilizador e comunicação sem fios
- Erros comuns
- Glossário
- Síntese
- Exercícios resolvidos
Introdução
Esta sebenta cobre o desenvolvimento completo de sistemas baseados em microcontrolador: desde a arquitetura interna do chip até um sistema a funcionar, com sensores a ler o mundo real, atuadores a responder, comunicação com outros dispositivos e uma interface para o utilizador interagir.
Um microcontrolador é um circuito integrado que junta, num só chip, processador, memória e periféricos de entrada/saída. Está dentro de eletrodomésticos, automóveis, máquinas industriais e equipamento médico: é o "cérebro" invisível de quase todos os produtos eletrónicos modernos. O percurso desta UC segue o de um profissional de eletrónica e automação: entender o hardware → programar em C/C++ → ler entradas → controlar saídas → comunicar → dar uma interface ao utilizador → construir e testar o circuito real.
Objetivos de aprendizagem (referencial): desenvolver um programa para leitura de entradas digitais e analógicas, controlo de saídas e comunicação série; implementar um sistema de controlo com sensores e atuadores baseado em microcontrolador; e desenvolver uma interface de utilizador para interação com esse sistema. No final, deves conseguir escolher, programar, montar e testar um sistema destes de forma autónoma, respeitando as normas de segurança e proteção ambiental.
1. Arquitetura de um microcontrolador
Um microcontrolador organiza-se em blocos internos que trabalham em conjunto:
- CPU (Central Processing Unit): executa as instruções do programa, uma a uma, num ciclo fetch → decode → execute (procurar a instrução, interpretá-la, executá-la).
- Memória de programa (ROM/Flash): guarda o código de forma permanente, mesmo sem alimentação.
- Memória de dados (RAM): guarda variáveis durante a execução; perde-se ao desligar.
- EEPROM: memória não volátil de leitura/escrita, usada para guardar configurações que devem sobreviver a um reset ou corte de energia.
- Periféricos de entrada e saída (GPIO): pinos configuráveis como entrada ou saída digital.
- Timers/contadores: contam ciclos de relógio, geram temporizações precisas, sinais PWM e interrupções periódicas.
- Conversores A/D e D/A: ligam o mundo analógico ao digital e vice-versa (secção 3).
Barramentos e registos
A CPU comunica com a memória e os periféricos através de barramentos (bus): conjuntos de linhas elétricas que transportam dados, endereços e sinais de controlo. O barramento de dados transporta a informação; o barramento de endereços identifica onde ler ou escrever.
Internamente, cada periférico é controlado através de registos: pequenas células de memória mapeadas em endereços específicos. Programar um microcontrolador é, no fundo, ler e escrever nestes registos, mesmo quando usamos funções de alto nível como digitalWrite(), que por baixo escreve um bit num registo de porta (ex.: PORTB).
Exemplo resolvido · identificar os blocos
Um sistema lê um sensor de temperatura, guarda o valor máximo do dia numa memória que sobrevive a cortes de energia, e acende um LED se ultrapassar um limite.
Resolução: o ADC (periférico) lê o sensor; a RAM guarda a leitura atual e as variáveis de cálculo durante a execução; a EEPROM guarda o valor máximo do dia, porque tem de sobreviver a um corte de energia; o GPIO de saída controla o LED. O programa que faz tudo isto está gravado na Flash.
2. Ferramentas de desenvolvimento e critérios de seleção
O fluxo de ferramentas
- IDE (Integrated Development Environment): editor de código, gestor de bibliotecas e compilação/carregamento num só programa (ex.: Arduino IDE, PlatformIO, MPLAB X, STM32CubeIDE).
- Compilador: traduz o código C/C++ em linguagem máquina executável pelo microcontrolador.
- Simulador: executa o código sem hardware físico, útil para validar lógica antes de montar o circuito.
- Debugger de hardware: liga-se fisicamente ao microcontrolador para parar o programa, ver variáveis e avançar instrução a instrução.
O ciclo de desenvolvimento embebido é: escrever → compilar → carregar (upload/flash) → executar → depurar. Ao contrário de um programa de computador, não há sistema operativo por trás na maioria dos casos: o programa corre isolado, diretamente sobre o hardware.
Critérios de seleção de um microcontrolador
Escolher o microcontrolador certo é uma aptidão central desta UC. Os critérios a pesar:
| Critério | Porquê importa |
|---|---|
| Nº de pinos I/O | tem de chegar para todos os sensores/atuadores do projeto |
| Memória (Flash/RAM) | o programa e as variáveis têm de caber |
| Velocidade de relógio | tarefas em tempo real exigem mais |
| Periféricos integrados | ADC, PWM, UART/SPI/I2C evitam hardware extra |
| Consumo de energia | crítico em sistemas alimentados a bateria |
| Custo e disponibilidade | viabilidade de um projeto em série |
| Ecossistema (IDE, bibliotecas, comunidade) | reduz o tempo de desenvolvimento |
Nenhuma seleção se faz sem consultar a documentação técnica do fabricante: o datasheet (especificações elétricas, pinout, limites absolutos de tensão e corrente), as application notes (exemplos de circuitos recomendados) e o reference manual (descrição detalhada de cada periférico e dos seus registos).
Exemplo resolvido · escolher entre dois microcontroladores
Um projeto é um sensor de temperatura a bateria, que acorda de hora a hora, envia uma leitura por Bluetooth e volta a "dormir". Compara um microcontrolador de 8 bits simples (baixo consumo, sem rádio) com um de 32 bits com Bluetooth integrado.
Resolução: o critério decisivo aqui é o consumo e a necessidade de comunicação sem fios integrada. Um microcontrolador de 32 bits com Bluetooth Low Energy (BLE) integrado evita um módulo externo e simplifica o circuito, e muitos destes chips têm modos de baixíssimo consumo em repouso. A escolha certa depende do datasheet: comparar a corrente em modo sleep de ambos antes de decidir, não assumir que "mais simples = menos consumo".
3. Conversores A/D e D/A
O mundo real é analógico (temperatura, luz, pressão, tensão contínua variável); o microcontrolador só processa valores digitais.
- ADC (Analog-to-Digital Converter): converte uma tensão analógica num número digital, com uma resolução em bits. Um ADC de 10 bits produz valores de 0 a 1023 (1024 níveis possíveis).
- DAC (Digital-to-Analog Converter): faz o inverso, gera uma tensão analógica a partir de um valor digital. Muitos microcontroladores simples não têm DAC dedicado e simulam saída "analógica" com PWM (secção 8).
Fórmula de conversão
tensão = leitura_ADC × (Vref / (2^n − 1))
onde Vref é a tensão de referência do ADC (normalmente a tensão de alimentação, ex.: 5 V ou 3,3 V) e n é a resolução em bits.
Exemplo resolvido · converter uma leitura
Um ADC de 10 bits, referência de 5 V, devolve o valor leitura = 614.
Resolução: tensão = 614 × (5 / 1023) ≈ 3,00 V. Se o sensor ligado converte 10 mV por grau Celsius com 0 V a 0°C, a temperatura seria 3,00 / 0,01 = 300°C · um valor irrealista, sinal de que o sensor teria outra escala; o método (leitura → tensão → grandeza física, usando sempre a fórmula do datasheet do sensor) é o que importa fixar.
4. Linguagem C/C++ para microcontroladores
Estrutura de um programa
#include <biblioteca.h>
void setup() {
// corre uma vez: configurar pinos, periféricos
}
void loop() {
// corre em ciclo infinito: a lógica do programa
}
O setup() trata da inicialização (direção dos pinos, velocidade da UART, etc.) e corre uma única vez. O loop() é o "coração" do programa: repete indefinidamente enquanto houver alimentação. Sem sistema operativo por trás, não há "sair do programa".
Tipos de dados
Em sistemas com pouca memória, o tipo de dados certo poupa recursos escassos:
| Tipo | Tamanho típico | Uso recomendado |
|---|---|---|
bool |
1 bit (armazenado em 1 byte) | flags, estados on/off |
uint8_t |
8 bits (0 a 255) | contadores pequenos, bytes de comunicação |
int / int16_t |
16 bits | valores com sinal, cálculos gerais |
float |
32 bits | valores decimais, usar com moderação |
Usar float em excesso num microcontrolador pequeno pode esgotar memória e tornar o programa lento. Preferir inteiros sempre que a precisão permitir.
Loops, condicionais e funções
- Condicionais (
if/else,switch): tomam decisões consoante o estado das entradas. - Loops (
for,while): repetem ações, como percorrer vários sensores. - Funções: organizam o código em blocos reutilizáveis e legíveis.
void verificarTemperatura() {
int leitura = analogRead(SENSOR);
if (leitura > LIMITE) {
ligarVentoinha();
} else {
desligarVentoinha();
}
}
Manipulação de bits e portas
Trabalhar diretamente com bits de um registo é necessário quando não há função de alto nível disponível, ou quando se quer controlo fino e eficiente:
- AND (
&): para ler ou limpar um bit específico. - OR (
|): para ligar (set) um bit sem afetar os outros. - XOR (
^): para inverter (toggle) um bit. - Deslocamento (
<<,>>): para posicionar um bit no lugar certo do registo.
PORTB |= (1 << 3); // liga o bit 3, mantém os restantes
PORTB &= ~(1 << 3); // desliga o bit 3
PORTB ^= (1 << 3); // inverte o bit 3
Exemplo resolvido · ligar um bit sem apagar os outros
PORTB está atualmente em 00000101 (bits 0 e 2 ligados). Pretende-se ligar também o bit 4, sem alterar os restantes.
Resolução: usar
PORTB |= (1 << 4);. A máscara(1 << 4)é00010000; com OR, só o bit 4 é forçado a 1, os restantes bits mantêm o valor que já tinham. O resultado é00010101. Se em vez disso se escrevessePORTB = (1 << 4);, o resultado seria00010000, apagando os bits 0 e 2 por engano.
Assembly para casos de uso específicos
O Assembly é a linguagem mais próxima do hardware: cada instrução corresponde diretamente a uma operação da CPU. Usa-se sobretudo em:
- Rotinas críticas de tempo, onde cada ciclo de relógio conta.
- Bootloaders e código de arranque muito próximo do hardware.
- Otimização de trechos pequenos identificados como o "gargalo" de um programa em C.
Na prática profissional, programa-se maioritariamente em C/C++ e recorre-se a Assembly apenas em blocos isolados e bem justificados, ou para compreender o código gerado pelo compilador ao depurar um problema de baixo nível.
5. Entradas digitais e analógicas
Entradas digitais e o problema do debouncing
Uma entrada digital só tem dois estados: HIGH ou LOW. Um botão liga o pino a Vcc ou GND consoante é premido; uma resistência de pull-up ou pull-down garante um nível estável quando o botão não está premido.
pinMode(BOTAO, INPUT_PULLUP);
if (digitalRead(BOTAO) == LOW) { /* premido */ }
Um botão mecânico não muda de estado de forma limpa: os contactos "ressaltam" (bounce) durante alguns milissegundos, gerando várias transições falsas que, sem tratamento, seriam lidas como vários cliques.
- Debouncing por software: ignorar novas leituras durante um pequeno intervalo (20-50 ms) depois de detetada uma mudança.
- Debouncing por hardware: um pequeno condensador RC filtra as oscilações antes do sinal chegar ao pino.
if (digitalRead(BOTAO) == LOW) {
delay(30);
if (digitalRead(BOTAO) == LOW) { /* clique confirmado */ }
}
Entradas analógicas: sensores
Sensores de temperatura, luz (LDR) ou pressão entregam uma tensão proporcional à grandeza medida, lida pelo ADC (ver secção 3).
Exemplo resolvido · debouncing com contador
Sem debounce, um contador de cliques incrementa 3 a 5 vezes por cada clique real. Corrige-se o código.
Resolução: antes:
if (digitalRead(BOTAO)==LOW) { cliques++; }dentro doloop(), sem espera. Depois: adicionar uma espera de confirmação e só contar a transição de HIGH para LOW uma vez.c if (digitalRead(BOTAO) == LOW && estadoAnterior == HIGH) { delay(30); if (digitalRead(BOTAO) == LOW) cliques++; } estadoAnterior = digitalRead(BOTAO);Guardar oestadoAnteriorevita contar o mesmo clique repetidamente enquanto o botão continua premido.
6. Saídas: LEDs, displays, motores e relés
LEDs e indicadores
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);
Um LED precisa sempre de uma resistência limitadora de corrente em série, para não exceder a corrente máxima do pino nem a do LED.
Displays
| Display | Características | Comunicação típica |
|---|---|---|
| LED de 7 segmentos | mostra dígitos | pinos diretos ou driver dedicado |
| LCD alfanumérico (16x2) | mostra texto | paralelo ou I2C |
| OLED | pequeno, nítido | I2C ou SPI |
lcd.begin(16, 2);
lcd.print("Temp: 23.5 C");
PWM para motores e brilho
O PWM (Pulse Width Modulation) simula uma saída "analógica" ligando/desligando o pino muito rapidamente, variando a percentagem de tempo ligado (duty cycle).
analogWrite(MOTOR, 128); // ~50% duty cycle, de 0 a 255
Motores exigem normalmente um driver de motor (ponte H) entre o microcontrolador e o motor, porque o pino não fornece corrente suficiente.
Relés
Um relé permite controlar cargas de maior tensão e corrente (ex.: 230 V AC) com um sinal digital de baixa potência. O microcontrolador ativa uma bobina de baixa potência através de um transístor ou driver dedicado; esta fecha um contacto que liga a carga real. Um díodo de roda livre (flyback), em paralelo com a bobina, protege o circuito da tensão inversa gerada quando esta desliga.
Exemplo resolvido · duty cycle e velocidade
Um motor DC deve rodar a aproximadamente 70% da velocidade máxima, usando analogWrite() de 0 a 255.
Resolução: duty cycle = 70% de 255 = 0,70 × 255 ≈ 178. Instrução:
analogWrite(MOTOR, 178);. Nota: a relação entre duty cycle e velocidade real não é sempre perfeitamente linear (atrito, carga do motor), mas é uma boa aproximação de projeto.
7. Comunicação série: UART, SPI e I2C
UART
A UART transmite dados bit a bit, em série, sem relógio partilhado. Ambos os lados têm de usar a mesma velocidade (baud rate), ex.: 9600 ou 115200 bps, e usa 2 fios: TX e RX, cruzados entre os dois dispositivos.
Serial.begin(9600);
Serial.println("Sistema iniciado");
Cada byte segue uma trama: bit de start, bits de dados, bit de paridade (opcional), bit(s) de stop. É ideal para ligações ponto a ponto (microcontrolador ↔ computador, ↔ módulo GPS/Bluetooth) e é a principal ferramenta de diagnóstico durante o desenvolvimento.
SPI
O SPI (Serial Peripheral Interface) é síncrono, com 4 linhas: SCK (relógio), MOSI (mestre→escravo), MISO (escravo→mestre) e SS/CS (seleção do escravo). Um único mestre controla vários escravos, cada um com a sua linha CS dedicada. É rápido, ao custo de mais fios.
I2C
O I2C (Inter-Integrated Circuit) é síncrono, com apenas 2 fios partilhados: SDA (dados) e SCL (relógio). Cada dispositivo tem um endereço único, permitindo dezenas de sensores/módulos partilharem a mesma linha. Requer resistências de pull-up em SDA e SCL.
| Protocolo | Fios | Velocidade | Nº de dispositivos |
|---|---|---|---|
| UART | 2 (TX/RX) | média | 2 (ponto a ponto) |
| SPI | 4 ou mais | alta | vários (1 CS cada) |
| I2C | 2 (SDA/SCL) | média/baixa | vários (endereço único) |
Exemplo resolvido · escolher o protocolo certo
Um projeto tem 6 sensores I2C compatíveis e apenas 4 pinos digitais livres no microcontrolador escolhido.
Resolução: I2C. Com apenas 2 fios partilhados (SDA e SCL), todos os 6 sensores podem ligar-se ao mesmo barramento, desde que cada um tenha um endereço diferente (ou configurável por pino/resistência). Usar SPI exigiria uma linha CS dedicada por sensor, o que não caberia nos 4 pinos livres.
8. Interrupções
Uma interrupção suspende temporariamente o programa principal para executar de imediato uma rotina prioritária, a ISR (Interrupt Service Routine), voltando depois ao ponto onde estava.
- Interrupções externas: disparadas por um sinal físico num pino dedicado (ex.: mudança de nível ao premir um botão).
- Interrupções internas: disparadas por periféricos internos, como um timer a atingir um valor, ou o fim de uma receção UART.
attachInterrupt(digitalPinToInterrupt(PINO), rotinaISR, FALLING);
void rotinaISR() {
flagEvento = true;
}
Uma interrupção é a alternativa a "verificar constantemente" (polling) uma entrada no loop(), o que desperdiça tempo de processamento e pode falhar eventos rápidos. Boa prática: a ISR deve ser curta, apenas marcar uma variável (flag, declarada volatile); o processamento pesado faz-se no loop() principal.
Exemplo resolvido · decidir polling vs interrupção
Um sistema tem um botão de paragem de emergência e um sensor de temperatura lido a cada segundo.
Resolução: o botão de emergência justifica interrupção externa: a paragem tem de ser imediata, independentemente do que o programa esteja a fazer. O sensor de temperatura, lido periodicamente e sem urgência de milissegundos, pode continuar em polling dentro do
loop(), ou usar um timer interno para marcar quando é altura de ler de novo.
9. Sensores, atuadores e controlo dinâmico
Um sistema de controlo típico segue o ciclo ler sensor → decidir → atuar, repetido continuamente:
void loop() {
int temperatura = lerSensor();
if (temperatura > LIMITE) {
ligarVentoinha();
} else {
desligarVentoinha();
}
}
Resposta dinâmica: histerese
Um limiar único faz o atuador oscilar rapidamente (ligar/desligar) quando a leitura ronda o valor de corte. A histerese usa dois limiares diferentes: liga acima de um valor, desliga abaixo de outro (mais baixo), criando uma "zona morta" no meio.
if (temperatura > LIMITE_LIGAR) ventoinhaLigada = true;
if (temperatura < LIMITE_DESLIGAR) ventoinhaLigada = false;
Outras técnicas de resposta dinâmica
- Filtragem/média móvel: suavizar leituras ruidosas de um sensor antes de decidir.
- Controlo proporcional simples: a intensidade da resposta (ex.: velocidade do motor) varia com a diferença entre o valor lido e o desejado, em vez de ser tudo ou nada.
Exemplo resolvido · histerese num termóstato
Um termóstato deve ligar o aquecimento abaixo de 18°C e desligá-lo só acima de 20°C, evitando ligar/desligar constantemente perto de um único valor.
Resolução:
c if (temperatura < 18.0) aquecimentoLigado = true; if (temperatura > 20.0) aquecimentoLigado = false;Entre 18°C e 20°C, o estado mantém-se como estava (não há decisão nova), evitando oscilações rápidas junto de um único limiar. É exatamente o comportamento de um termóstato doméstico real.
10. Interface de utilizador e comunicação sem fios
Interfaces locais
- Botões: para o utilizador dar comandos diretos (ligar, ajustar, confirmar).
- Displays: para mostrar estado, valores lidos, mensagens.
- Interfaces gráficas simples: menus navegáveis com botões e um display, para configurar parâmetros sem computador.
Comunicação sem fios
- Bluetooth (clássico ou BLE): curto alcance, baixo consumo, ideal para apps móveis e configuração local.
- Wi-Fi: alcance maior, liga o sistema à rede local ou à internet; permite dashboards web e notificações remotas.
O microcontrolador expõe dados e comandos (ex.: um pequeno servidor web, ou mensagens por Bluetooth) que uma app de smartphone ou computador lê e apresenta de forma amigável ao utilizador final.
Exemplo resolvido · escolher entre Bluetooth e Wi-Fi
Um sensor de porta de garagem, a bateria, deve avisar o telemóvel do dono quando alguém a abre, apenas quando ele está perto de casa.
Resolução: Bluetooth Low Energy (BLE). O alcance limitado não é problema (o aviso só interessa quando o dono está perto), e o consumo baixíssimo do BLE prolonga muito a duração da bateria face a Wi-Fi, que exige mais energia para se manter ligado à rede.
Erros comuns
- Confundir Flash com RAM: esquecer que a RAM perde os dados ao desligar e guardar aí algo que devia estar em EEPROM.
- Ligar um sensor ou atuador diretamente a um pino sem verificar a corrente máxima no datasheet, arriscando queimar o microcontrolador.
- Usar
=em vez de|=ao manipular um registo, apagando bits que não deviam mudar. - Ignorar o debouncing de botões, contando vários cliques por cada clique real.
- Esquecer as resistências de pull-up no barramento I2C, causando comunicação instável ou inexistente.
- Colocar código demorado numa ISR, bloqueando o resto do sistema durante uma interrupção.
- Saltar a fase de simulação e ir direto à montagem física, perdendo tempo a corrigir erros que a simulação teria apanhado.
- Testar só o sistema completo no fim, sem validar cada bloco (alimentação, sensor, atuador, comunicação) isoladamente primeiro.
Glossário
- Microcontrolador · chip que integra CPU, memória e periféricos, dedicado a uma função.
- GPIO · pino de entrada/saída de uso geral.
- ADC / DAC · conversor analógico-digital / digital-analógico.
- IDE · ambiente integrado de desenvolvimento.
- Debounce · tratamento do ressalto mecânico de um botão.
- Pull-up / pull-down · resistência que garante um nível estável numa entrada digital.
- PWM · modulação por largura de pulso, simula uma saída analógica.
- UART · comunicação série assíncrona ponto a ponto.
- SPI · comunicação série síncrona com linha de seleção dedicada por dispositivo.
- I2C · comunicação série síncrona com endereçamento, em 2 fios partilhados.
- Interrupção / ISR · mecanismo (e rotina) que suspende o programa principal para tratar um evento prioritário.
- Histerese · uso de dois limiares para evitar oscilação de um atuador junto de um valor de corte.
- PCB · placa de circuito impresso.
- Datasheet · documento técnico do fabricante com as especificações de um componente.
Síntese
Um sistema baseado em microcontrolador constrói-se sempre pela mesma sequência: arquitetura e escolha do chip (CPU, memória, periféricos, critérios de seleção) → programação (C/C++, estruturas de controlo, manipulação de bits) → entradas (digitais com debounce, analógicas com ADC) → saídas (LEDs, displays, PWM, motores, relés) → comunicação (UART, SPI, I2C, interrupções, sem fios) → circuito de suporte e PCB → metodologia de projeto e testes (requisitos → simulação → montagem → validação com multímetro e osciloscópio). Domina este fluxo e serás capaz de desenvolver, com autonomia, qualquer sistema deste tipo, dos mais simples aos mais complexos.
Exercícios resolvidos
1. Um sistema tem de acender um LED sempre que um sensor de luz (LDR) detetar escuridão, mas não deve piscar quando a luz está no limiar. Que técnica se aplica e como?
Resolução: aplica-se histerese: definir um limiar de "ligar" (ex.: leitura ADC abaixo de 300) e um limiar de "desligar" diferente e mais alto (ex.: acima de 350). Entre os dois valores, o estado do LED mantém-se, evitando que ele pisque quando a leitura oscila perto de um único limiar.
2. Porque é que PORTB = 0b00000001; pode ser perigoso num sistema onde outros bits de PORTB já controlam outras saídas?
Resolução: porque a atribuição
=substitui todo o registo, apagando o estado de todos os outros bits (outras saídas que possam estar ligadas). O correto é usarPORTB |= 0b00000001;para ligar só o bit pretendido sem afetar os restantes.
3. Um botão está a gerar múltiplos cliques por cada pressão física. Qual é a causa e como se resolve por software?
Resolução: a causa é o ressalto (bounce) dos contactos mecânicos do botão, que gera várias transições elétricas numa única pressão. Resolve-se com debouncing por software: depois de detetar uma transição, esperar um pequeno intervalo (20-50 ms) e confirmar que o estado se mantém antes de aceitar o clique como válido.
4. Um projeto precisa de ligar 8 sensores a um microcontrolador que só tem 3 pinos digitais livres. Que protocolo de comunicação resolve o problema, e porquê?
Resolução: I2C, porque usa apenas 2 fios partilhados (SDA e SCL) para comunicar com todos os dispositivos, desde que cada um tenha um endereço único no barramento. Com apenas 3 pinos livres, nem UART (2 dispositivos apenas) nem SPI (exige uma linha CS por dispositivo) resolveriam o problema com tantos sensores.
5. Porque é que uma rotina de interrupção (ISR) não deve conter um delay() longo?
Resolução: porque, enquanto a ISR está a correr, o programa principal (e frequentemente outras interrupções) fica bloqueado. Um
delay()longo numa ISR atrasa toda a resposta do sistema a outros eventos, incluindo eventos urgentes. A boa prática é a ISR ser curta, apenas marcar uma variávelvolatile, e deixar o processamento pesado para oloop()principal.
6. Antes de montar fisicamente um circuito com microcontrolador, que passo da metodologia de projeto não deve ser saltado, e que instrumento confirma a montagem depois?
Resolução: não deve ser saltada a simulação em software de desenho e simulação de circuitos, que apanha erros lógicos e de ligação antes de gastar componentes reais. Depois de montado, o multímetro confirma a tensão de alimentação correta antes de ligar o microcontrolador, e o osciloscópio confirma a forma de sinais dinâmicos como PWM ou comunicação série.