
Passo 1 de 9
Separe os tempos de uma atualização
Diferencie os tempos planejados dos tempos que realmente acontecem em uma tarefa periódica.
Trilha de aprendizado · Nível 13 · Tutorial 1
Definir um período de atualização e verificar, no Arduino Uno próprio, se aquisição, cálculo e saída cabem no tempo disponível com margem.
Separe os tempos de uma atualização
Diferencie os tempos planejados dos tempos que realmente acontecem em uma tarefa periódica. 2 min
Escolha um período inicial justificável
Escolha um período inicial comparando a banda útil, a dinâmica conhecida, o atraso aceitável e o tempo que restará para executar o programa. 2 min
Distribua o orçamento de execução
Distribua o período entre a tarefa periódica, custos indiretos e uma reserva antes de medir o comportamento no Uno. 2 min
Meça durações com micros
Use micros() para delimitar e interpretar medições curtas de duração no Arduino Uno R3. 2 min
Interprete latência e jitter
Use registros de tempo para distinguir latência, jitter, intervalos reais e perda de prazo. 2 min
Trate atrasos sem acumular trabalho vencido
Mantenha uma referência periódica, descarte liberações vencidas de forma contada e execute somente a atualização mais recente disponível. 3 min
Instrumente uma tarefa no seu Uno
Execute localmente uma tarefa periódica instrumentada no Arduino Uno R3 e obtenha métricas iniciais de duração, latência, intervalos, descartes e perdas de prazo. 3 min
Teste variações e revise a margem
Confronte o orçamento com condições de execução diferentes, teste a política de descarte e revise a margem com base em evidências limitadas. 2 min
Valide e registre sua decisão
Consolide período, orçamento, medições e política de recuperação em um registro técnico conciso e prudente. 3 min

Passo 1 de 9
Diferencie os tempos planejados dos tempos que realmente acontecem em uma tarefa periódica.
Uma tarefa periódica tem instantes previstos para atualizar. O período programado (T) é a distância entre dois desses instantes previstos — não é, necessariamente, o tempo que o código leva para executar.
Nesta trilha, cada atualização terá prazo relativo igual ao período: se uma atualização era prevista para t₀, ela deve terminar até t₀ + T. Essa convenção facilita verificar se há tempo para a próxima atualização.

Compare sempre os marcos previstos com os eventos que realmente ocorreram.
Leia uma atualização por quatro trechos:
Assim, duração e intervalo real começam em referências diferentes. Uma execução pode ser curta, mas começar atrasada porque outra atividade ocupou o processador antes dela.
Exemplo
Considere T = 10 ms. Uma atualização era prevista para 20 ms, começou em 22 ms e terminou em 25 ms. A seguinte começou em 31 ms.
O início foi posterior ao previsto, mas isso não implica, sozinho, que o prazo foi perdido.
Associe cada grandeza à definição correta.
Faça as associações.
Toque em um item e depois no par correspondente.
Se uma atualização dura pouco, ela necessariamente começou no instante previsto e cumpriu o prazo.

Passo 2 de 9
Escolha um período inicial comparando a banda útil, a dinâmica conhecida, o atraso aceitável e o tempo que restará para executar o programa.
Uma escolha inicial de período é uma hipótese de engenharia, não uma fórmula universal. Use as informações já conhecidas sobre o sinal e a dinâmica para comparar candidatos.
Considere dois critérios:
Um período menor traz atualizações mais frequentes e potencialmente menor atraso de resposta. Em troca, deixa menos tempo para aquisição, cálculo, saída e as demais atividades do firmware.

O mesmo sistema pode ser atualizado em ritmos diferentes; compare o atraso e a quantidade de oportunidades de reagir.
Dica
Não existe uma razão fixa, como “sempre usar dez atualizações por constante de tempo”, que sirva para todo sistema. Uma aplicação pode tolerar poucas atualizações em uma dinâmica lenta; outra pode exigir resposta mais rápida mesmo com a mesma constante de tempo.
A decisão também é provisória: nos próximos steps, você vai montar o orçamento e medir o que o Uno realmente consegue executar com margem.
Caso de comparação: um sinal tem banda útil de 5 Hz e o comportamento relevante possui constante de tempo conhecida de 200 ms. A aplicação aceita até cerca de 50 ms de espera até uma nova atualização.
Pelo critério mínimo de Nyquist, a taxa deve ser maior que 10 Hz; portanto, o período deve ser menor que 100 ms. Compare agora três candidatos. A coluna “atualizações por τ” é apenas uma forma de visualizar a dinâmica; ela não é uma regra de aprovação isolada.
Comparação de períodos candidatos para o exemplo.
| Período | Taxa | Atualizações por τ | Leitura inicial |
|---|---|---|---|
| 20 ms | 50 Hz | 10 | Resposta frequente; pouco tempo para o programa |
| 50 ms | 20 Hz | 4 | Atende a banda e o atraso aceito |
| 80 ms | 12,5 Hz | 2,5 | Atende Nyquist, mas excede o atraso aceito |
Exemplo
Para este caso, 50 ms é uma escolha inicial justificável: gera 20 Hz, acima dos 10 Hz mínimos associados à banda de 5 Hz; oferece quatro atualizações em 200 ms; e não ultrapassa os 50 ms de espera declarados.
Já 80 ms não serve porque viola o requisito de atraso, apesar de passar no critério mínimo de amostragem. O período de 20 ms não é automaticamente melhor: ele só será mantido se o orçamento e as medições mostrarem tempo suficiente com margem.
No caso apresentado, qual justificativa sustenta melhor a escolha provisória de 50 ms?
Selecione a melhor justificativa.

Passo 3 de 9
Distribua o período entre a tarefa periódica, custos indiretos e uma reserva antes de medir o comportamento no Uno.
Um período é um recipiente de tempo: tudo o que pode afetar a próxima atualização precisa caber nele. Comece separando a tarefa crítica — adquirir, calcular e atualizar a saída — das demais atividades que também disputam o processador.
Um orçamento preliminar não é uma medição: é uma estimativa declarada para orientar o projeto. Ele deve reservar tempo para variações, caminhos condicionais, interrupções e diagnósticos. Depois, os valores serão confrontados com medições no Uno.

Cada bloco consome parte do mesmo período. A reserva não é tempo “sobrando”: ela protege o atendimento contra variações.
Monte o orçamento em blocos. Inclua custos pequenos que costumam ser esquecidos: verificar se chegou o instante da tarefa, marcas de tempo para diagnóstico, interrupções e o restante do loop().
A comunicação serial deve ficar fora do trecho crítico sempre que possível, mas não fica fora do orçamento. Formatar e enviar uma mensagem pode consumir tempo ou bloquear; portanto, pode atrasar o início da atualização seguinte.
Exemplo de orçamento preliminar para período de 10.000 µs. Os valores são estimativas de projeto, não medições do seu Uno.
| Bloco | Estimativa (µs) | Papel |
|---|---|---|
| Agendamento | 120 | Verificar liberação |
| Aquisição | 260 | Ler entrada |
| Cálculo | 90 | Processar valor |
| Atualização da saída | 50 | Escrever LED ou PWM |
| Instrumentação | 120 | Marcas de tempo |
| Outras atividades | 800 | Restante do loop |
| Diagnóstico serial | 3.800 | Formatar e transmitir |
| Interrupções previstas | 500 | Reserva para atendimentos |
| Margem explícita | 4.260 | Variações e caminhos extras |
Exemplo
A duração estimada da tarefa crítica neste exemplo é 260 + 90 + 50 = 400 µs. Isso é bem menor que 10.000 µs, mas ainda não prova que ela começará no instante previsto: uma atividade serial ou outro trecho do loop pode estar em execução quando chegar a hora.
Por isso, considere dois testes no orçamento: (1) a soma de todos os blocos cabe no período? (2) há margem positiva e justificável? Se a reserva for zero, qualquer variação já transforma a estimativa em atraso.
No orçamento da tabela, qual é a reserva restante em microssegundos após contabilizar todos os blocos, exceto a própria margem?
Escreva pelo menos 1 caracteres (0/1).
Qual proposta é mais adequada para um orçamento preliminar de uma tarefa periódica?

Passo 4 de 9
Use micros() para delimitar e interpretar medições curtas de duração no Arduino Uno R3.
Para medir a duração de um trecho, capture uma marca de tempo imediatamente antes e outra imediatamente depois dele. A diferença entre as marcas é a duração observada.
No Uno R3, use marcas e diferenças sem sinal de 32 bits (uint32_t). Isso mantém o cálculo correto mesmo quando o contador de micros() retorna a zero.
A marca inicial deve ficar próxima do começo que você quer medir; a final, logo após o fim. Tudo que estiver entre elas — inclusive uma interrupção que ocorra nesse intervalo — compõe a duração observada.

Meça somente o trecho que interessa: as marcas delimitam o intervalo observado.
Este padrão mede a duração da função tarefa(). O código não deve imprimir pela Serial dentro do trecho medido: comunicação e formatação também consomem tempo e devem ser orçadas separadamente.
uint32_t inicio = micros();
tarefa();
uint32_t fim = micros();
uint32_t duracaoUs = fim - inicio;No Uno R3 de 16 MHz, com a configuração padrão, micros() avança em passos de 4 µs. Portanto, uma duração lida como 0 significa apenas que o trecho ficou abaixo da resolução observável, ou caiu entre duas atualizações da contagem; não significa execução instantânea.
A própria leitura de micros() também tem custo. Para trechos muito curtos, a instrumentação e a quantização podem ser comparáveis ao tempo que você quer medir. Meça blocos significativos e interprete valores pequenos com prudência.
Atenção
micros() depende do Timer0. Mantenha a configuração padrão desse temporizador e evite desabilitar interrupções por períodos longos. Caso contrário, a contagem pode deixar de representar adequadamente o tempo transcorrido.
Exemplo
A contagem de micros() é de 32 bits sem sinal e retorna a zero aproximadamente a cada 71,6 minutos. Isso não exige um tratamento especial na subtração usual.
Exemplo: pouco antes do retorno, inicio = 4294967292; após o retorno, fim = 8. Em aritmética sem sinal de 32 bits, fim - inicio resulta em 12: o intervalo real foi 12 µs.
A regra vale desde que o intervalo medido seja menor que uma volta completa do contador — condição amplamente atendida ao medir uma tarefa curta.

Com marcas sem sinal de 32 bits, a diferença preserva um intervalo curto mesmo através do retorno a zero.
Complete a captura da marca final e o cálculo da duração observada.
uint32_t inicio = micros();
// trecho cuja duração será observada
tarefa();
uint32_t fim = ();
uint32_t duracaoUs = fim - ;
Passo 5 de 9
Use registros de tempo para distinguir latência, jitter, intervalos reais e perda de prazo.
Em cada atualização, compare o instante previsto com a marca de início registrada pelo software, idealmente imediatamente antes ou depois da aquisição. A diferença é a latência de atendimento:
latência = início efetivo − instante previsto
Se a atualização estava prevista para 11.000 µs e começou em 11.100 µs, a latência foi 100 µs.
Essa marca descreve quando a tarefa realmente começou a ser atendida. Ela não é o instante em que uma mensagem de diagnóstico aparece no Monitor Serial: a transmissão e a formatação serial podem ocorrer bem depois e não devem virar a referência da aquisição.

A distância entre a marca prevista e o início efetivo é a latência. Quando essa distância muda de uma atualização para outra, há variação temporal no atendimento.
Jitter é a variação desses tempos ao longo das atualizações. Um atraso constante de 100 µs em todas as chamadas é latência, mas não produz variação entre elas. Já atrasos de 0 µs, 100 µs e 50 µs indicam atendimento variável.
Também registre o intervalo real entre inícios consecutivos:
intervalo[i] = início[i] − início[i−1]
Para uma sequência observada, anote o menor intervalo, o maior intervalo e a amplitude: máximo − mínimo. São indicadores observados no ensaio, não uma garantia para todas as condições possíveis.
Considere período programado de 1.000 µs e prazo relativo também de 1.000 µs. Portanto, cada prazo termina 1.000 µs depois do respectivo instante previsto.
Caso A mantém o mesmo deslocamento; caso B varia o deslocamento. No caso B, a segunda atualização também ultrapassa seu prazo.
| Caso | Previsto | Início | Duração | Fim | Latência |
|---|---|---|---|---|---|
| A1 | 10.000 | 10.100 | 700 | 10.800 | 100 |
| A2 | 11.000 | 11.100 | 700 | 11.800 | 100 |
| A3 | 12.000 | 12.100 | 700 | 12.800 | 100 |
| B1 | 10.000 | 10.000 | 700 | 10.700 | 0 |
| B2 | 11.000 | 11.100 | 920 | 12.020 | 100 |
| B3 | 12.000 | 12.050 | 700 | 12.750 | 50 |
Exemplo
No caso A, os intervalos reais são 1.000 µs e 1.000 µs. Mínimo = máximo = 1.000 µs; amplitude = 0 µs. Há latência constante de 100 µs, mas não há jitter observado nesses inícios.
No caso B, os intervalos são 1.100 µs e 950 µs. Mínimo = 950 µs; máximo = 1.100 µs; amplitude = 150 µs. Os atendimentos variaram.
Para verificar o prazo, não basta comparar a duração com o período. Use:
latência + duração ≤ prazo relativo
Em B2: 100 µs + 920 µs = 1.020 µs. O prazo era 1.000 µs; o fim em 12.020 µs passou 20 µs do limite de 12.000 µs.
Assim, B2 começou atrasada e perdeu o prazo. Já A1 começou 100 µs atrasada, porém terminou em 10.800 µs, antes do limite de 11.000 µs: início atrasado não implica, sozinho, perda de prazo.
No registro B2, o início efetivo foi 11.100 µs, o instante previsto foi 11.000 µs e a duração foi 920 µs. O prazo termina em 12.000 µs.
A atualização terminou quantos microssegundos depois do prazo? Preencha somente o número.
Atraso além do prazo: ___ µs
Qual afirmação interpreta corretamente a atualização B2?

Passo 6 de 9
Mantenha uma referência periódica, descarte liberações vencidas de forma contada e execute somente a atualização mais recente disponível.
Quando uma tarefa atrasa, definir a próxima agenda como agora + periodo desloca todas as liberações futuras. Um atraso isolado passa a determinar a cadência.
Mantenha nextDue como o próximo instante previsto. Ao encontrar uma ou mais liberações vencidas, avance essa referência em múltiplos inteiros do período. Assim, o atendimento atrasado não redefine os instantes planejados.

A referência permanece alinhada à grade periódica; apenas a liberação mais recente vencida é atendida.
Use uma definição única: nextDue é sempre a próxima liberação prevista que ainda não foi atendida nem descartada.
Quando agora alcança nextDue, calcule:
elapsed = agora - nextDue
skipped = elapsed / PERIOD_US
skipped informa quantos períodos completos se passaram depois de nextDue. A liberação atendida é:
scheduled = nextDue + skipped × PERIOD_US
As skipped liberações anteriores são descartadas. Depois de atender scheduled, a nova referência é scheduled + PERIOD_US. A aquisição é feita agora; ela não reconstrói dados dos instantes descartados.
Exemplo
Considere PERIOD_US = 1.000, nextDue = 10.000 e agora = 13.450 µs.
elapsed = 13.450 − 10.000 = 3.450 µsskipped = 3.450 / 1.000 = 3scheduled = 10.000 + 3 × 1.000 = 13.000 µsAs liberações de 10.000, 11.000 e 12.000 µs são descartadas: discarded += 3. A liberação de 13.000 µs é atendida uma única vez, com uma aquisição feita agora. Ao final, nextDue passa a 14.000 µs.
Não repita a leitura atual para fingir que ela foi adquirida nos três instantes passados.
Atenção
A subtração sem sinal continua válida através do retorno de micros(), desde que o intervalo real seja menor que uma volta completa. Porém, o teste de vencimento usado adiante converte a diferença para int32_t:
(int32_t)(now - nextDue) >= 0
Essa comparação só é inequívoca na meia faixa do contador: a diferença relevante deve ser muito menor que 2^31 µs, cerca de 35,8 minutos — e PERIOD_US também deve estar nessa faixa. Na prática, consulte o agendador continuamente no loop(), nunca depois de uma pausa longa. Isso é mais restritivo que a volta completa de aproximadamente 71,6 minutos de micros().
Trecho central com nextDue como próxima liberação pendente. Ele executa, no máximo, uma atualização em cada passagem pelo loop().
const uint32_t PERIOD_US = 1000;
uint32_t nextDue;
uint32_t discarded = 0;
uint32_t deadlineMisses = 0;
void loop() {
uint32_t now = micros();
if ((int32_t)(now - nextDue) >= 0) {
uint32_t elapsed = now - nextDue;
uint32_t skipped = elapsed / PERIOD_US;
uint32_t scheduled = nextDue + skipped * PERIOD_US;
discarded += skipped;
nextDue = scheduled + PERIOD_US;
uint32_t start = micros();
int reading = analogRead(A0); // aquisição nova, feita agora
digitalWrite(LED_BUILTIN, reading > 512 ? HIGH : LOW);
uint32_t end = micros();
// Prazo relativo de um período contado de scheduled.
if (end - scheduled > PERIOD_US) {
deadlineMisses++;
}
}
}
Há somente um if, não um laço que execute repetidamente a tarefa vencida. Mesmo que skipped seja 3 ou maior, ocorre no máximo uma atualização nesta passagem pelo loop().
discarded conta liberações que nem chegaram a executar. deadlineMisses conta outra coisa: uma atualização que foi executada, mas cujo end ficou depois de scheduled + PERIOD_US. Um descarte não é automaticamente uma perda de prazo da atualização atendida.
Complete o cálculo da liberação vencida mais recente e o avanço para a próxima referência. A atualização atendida continua sendo única; as liberações anteriores são contabilizadas em discarded.
uint32_t elapsed = now - nextDue;
uint32_t skipped = ;
uint32_t scheduled = ;
discarded += skipped;
nextDue = ;
runTask(scheduled);Com período de 1.000 µs, nextDue = 10.000 µs e agora = 13.450 µs, qual resultado segue a política apresentada?
Atenção
Evite usar um while para executar tarefas vencidas até “alcançar” a agenda. Essa recuperação pode monopolizar o loop(), aumentar ainda mais os atrasos e criar várias execuções com dados que não pertencem ao passado.
Descartes ocasionais podem ser uma política explícita. Porém, descartes frequentes indicam sobrecarga persistente: reduza trabalho, limite diagnósticos ou reveja o período somente se os requisitos de banda e dinâmica permitirem.

Passo 7 de 9
Execute localmente uma tarefa periódica instrumentada no Arduino Uno R3 e obtenha métricas iniciais de duração, latência, intervalos, descartes e perdas de prazo.
Monte apenas este ensaio de baixa energia: conecte o Uno R3 ao computador por USB, ligue A0 ao GND e não conecte motor, ponte H ou outra carga externa. O sketch lê A0, faz um cálculo simples e atualiza o LED integrado.
Com A0 no GND, a leitura tende a ficar próxima de zero; isso torna o sinal previsível para o primeiro teste. Abra a IDE Arduino, selecione sua placa e porta e deixe o Monitor Serial em 115200 baud.

Use somente USB, A0–GND e o LED integrado neste ensaio.
Dica
O período de referência será 10.000 µs (10 ms). As medições incluem aquisição, cálculo, saída e o trecho crítico completo. Uma interrupção que ocorra dentro de uma dessas janelas também aparece na duração medida.
Cole este primeiro bloco no início de um novo sketch.
const uint32_t PERIOD_US = 10000UL;
const uint32_t REPORT_US = 1000000UL;
uint32_t nextDue, nextReport;
uint32_t served = 0, discarded = 0, deadlineMisses = 0;
uint32_t maxAcq = 0, maxCalc = 0, maxOut = 0;
uint32_t maxCritical = 0, maxLatency = 0;
uint32_t minInterval = UINT32_MAX, maxInterval = 0;
uint32_t previousStart = 0;
bool hasPreviousStart = false;
uint32_t reportServed, reportDiscarded, reportMisses;
uint32_t reportAcq, reportCalc, reportOut, reportCritical;
uint32_t reportLatency, reportMinInterval, reportMaxInterval;
uint8_t reportPhase = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
uint32_t now = micros();
nextDue = now + PERIOD_US;
nextReport = now + REPORT_US;
}Cole este segundo bloco depois do anterior. As marcas internas separam aquisição, cálculo e saída; a janela de start até end mede o trecho crítico completo, inclusive o custo dessas marcas e interrupções que ocorram nele.
void runTask(uint32_t scheduled) {
uint32_t start = micros();
uint32_t latency = start - scheduled;
uint32_t t0 = micros();
int raw = analogRead(A0);
uint32_t t1 = micros();
int scaled = raw * 3 + 7;
uint32_t t2 = micros();
digitalWrite(LED_BUILTIN, scaled > 100 ? HIGH : LOW);
uint32_t end = micros();
uint32_t acq = t1 - t0;
uint32_t calc = t2 - t1;
uint32_t out = end - t2;
uint32_t critical = end - start;
if (acq > maxAcq) maxAcq = acq;
if (calc > maxCalc) maxCalc = calc;
if (out > maxOut) maxOut = out;
if (critical > maxCritical) maxCritical = critical;
if (latency > maxLatency) maxLatency = latency;
if (hasPreviousStart) {
uint32_t interval = start - previousStart;
if (interval < minInterval) minInterval = interval;
if (interval > maxInterval) maxInterval = interval;
}
previousStart = start;
hasPreviousStart = true;
if (latency + critical > PERIOD_US) deadlineMisses++;
served++;
}Cole este bloco. A função recalcula o instante atual ao ser chamada, preserva a referência periódica e executa no máximo uma atualização. Se você inserir mais adiante uma perturbação antes da chamada desta função, ela ainda calculará os descartes a partir do instante atual.
void serveDueTask() {
uint32_t now = micros();
if ((int32_t)(now - nextDue) >= 0) {
uint32_t elapsed = now - nextDue;
uint32_t skipped = elapsed / PERIOD_US;
uint32_t scheduled = nextDue + skipped * PERIOD_US;
discarded += skipped;
nextDue = scheduled + PERIOD_US;
runTask(scheduled);
}
}Complete o sketch com este bloco. O relatório é dividido em três linhas curtas. Cada linha só é enviada se houver espaço suficiente no buffer serial para ela inteira; assim, o envio adiado evita bloquear a tarefa por falta de espaço. Clique em Verificar e depois em Carregar.
bool sendLine(const char *line) {
int n = strlen(line);
if (n > 0 && Serial.availableForWrite() >= n) {
Serial.write((const uint8_t *)line, n);
return true;
}
return false;
}
void captureReport() {
reportServed = served; reportDiscarded = discarded;
reportMisses = deadlineMisses;
reportAcq = maxAcq; reportCalc = maxCalc; reportOut = maxOut;
reportCritical = maxCritical; reportLatency = maxLatency;
reportMinInterval = hasPreviousStart ? minInterval : 0;
reportMaxInterval = hasPreviousStart ? maxInterval : 0;
reportPhase = 1;
}
void emitReport() {
char line[72];
if (reportPhase == 1) {
snprintf(line, sizeof(line), "cont n=%lu d=%lu p=%lu\n",
(unsigned long)reportServed, (unsigned long)reportDiscarded,
(unsigned long)reportMisses);
} else if (reportPhase == 2) {
snprintf(line, sizeof(line), "dur aq=%lu ca=%lu sa=%lu cr=%lu\n",
(unsigned long)reportAcq, (unsigned long)reportCalc,
(unsigned long)reportOut, (unsigned long)reportCritical);
} else {
snprintf(line, sizeof(line), "tmp la=%lu in=%lu/%lu\n",
(unsigned long)reportLatency, (unsigned long)reportMinInterval,
(unsigned long)reportMaxInterval);
}
if (sendLine(line)) reportPhase++;
if (reportPhase == 4) reportPhase = 0;
}
void loop() {
serveDueTask();
uint32_t now = micros();
if (reportPhase == 0 && (int32_t)(now - nextReport) >= 0) {
captureReport();
nextReport = now + REPORT_US;
}
if (reportPhase != 0) emitReport();
}cont n=100 d=0 p=0 dur aq=112 ca=4 sa=8 cr=140 tmp la=16 in=9996/10008 cont n=200 d=0 p=0 dur aq=116 ca=4 sa=8 cr=144 tmp la=16 in=9996/10008
Os valores variam entre placas, versões do núcleo Arduino e condições de execução. As três linhas formam um único relatório: contadores, durações e tempos.
Cada conjunto de três linhas é um relatório:
cont: n = atualizações atendidas; d = liberações descartadas; p = atualizações executadas que terminaram após o prazo.dur: aq = maior duração de aquisição; ca = maior duração do cálculo; sa = maior duração da atualização de saída; cr = maior duração do trecho crítico completo.tmp: la = maior latência; in = menor/maior intervalo entre inícios.Todos os tempos são em microssegundos. O primeiro atendimento não entra em in, pois ainda não há início anterior. A formatação e a transmissão serial ficam fora de runTask(), mas pertencem ao orçamento: se consumirem tempo, podem atrasar o atendimento seguinte.
Atenção
Um in máximo maior que 10.000 µs não é automaticamente apenas jitter. Se d também aumentou, o intervalo foi ampliado porque uma ou mais atualizações foram descartadas. Registre descartes separadamente da variação comum dos atendimentos.
Após observar pelo menos três relatórios completos, registre os valores mais recentes de n, d, p, aq, ca, sa, cr, la e in. Houve descarte ou perda de prazo? Se os números diferirem do exemplo, isso é esperado. Informe também se A0 estava ligado ao GND.
Escreva pelo menos 40 caracteres (0/40).

Passo 8 de 9
Confronte o orçamento com condições de execução diferentes, teste a política de descarte e revise a margem com base em evidências limitadas.
Compare ensaios sob condições declaradas, mantendo a mesma placa, montagem com A0 no GND e período de 10.000 µs. Mude uma condição por vez e registre cr, la, in, d e p.
Use quatro condições: operação básica; perturbação dentro da tarefa; perturbação antes da decisão do agendador; e relatórios seriais periódicos. Uma perturbação interna tende a elevar a duração crítica (cr). Uma perturbação antes da decisão tende a elevar a latência (la) e, se atravessar períodos, pode gerar descartes (d).
A comunicação serial fica fora do trecho crítico, mas não é gratuita: formatação e escrita ocupam o loop() e podem atrasar o próximo atendimento.

A posição da perturbação muda a métrica predominante: dentro da tarefa aumenta a duração; antes da decisão pode aumentar latência e descartes.
Anote uma linha por condição. Os máximos observados só têm significado junto das condições declaradas do ensaio.
| Condição | Alteração | Efeito principal a observar |
|---|---|---|
| Básica | Sem perturbação | Referência para cr, la e in |
| Interna | Espera de 3.000 µs na tarefa | cr maior; componentes isolados preservados |
| Pré-atendimento | Espera única de 35.000 µs | la, d e intervalos extremos maiores |
| Serial | Relatórios durante a janela | Possível aumento de la ou in |
Faça os ensaios em execuções separadas, carregando o sketch a cada mudança de constante. A espera é proposital, finita e serve somente para testar as métricas.
Ensaio interno: use PERTURBAR_DENTRO_US = 3000 e PERTURBAR_ANTES_US = 0. A espera entra no trecho crítico completo, mas fica fora das janelas individuais de aquisição, cálculo e saída. Assim, cr deve crescer aproximadamente 3.000 µs, enquanto aq, ca e sa tendem a ficar próximos aos valores básicos.
Ensaio pré-atendimento: depois, use PERTURBAR_DENTRO_US = 0 e PERTURBAR_ANTES_US = 35000. A espera ocorre somente depois de três tarefas atendidas, para que existam inícios anteriores e posteriores para comparar.
Adicione este trecho junto às constantes e funções globais do sketch da etapa anterior. Para cada ensaio, altere somente os valores das duas constantes conforme a instrução desta tela.
const uint32_t PERTURBAR_DENTRO_US = 3000UL;
const uint32_t PERTURBAR_ANTES_US = 0UL;
bool prePerturbUsed = false;
void esperaAtivaUs(uint32_t duracaoUs) {
uint32_t inicio = micros();
while ((uint32_t)(micros() - inicio) < duracaoUs) {
// Espera proposital e limitada.
}
}Em runTask(), insira a primeira linha após o cálculo de latency e antes de t0 = micros(). Depois, substitua serveDueTask() por esta versão. A perturbação pré-atendimento só ocorre depois de três tarefas atendidas; portanto, o intervalo ampliado poderá ser comparado com o início anterior.
// Em runTask(), insira após:
// uint32_t latency = start - scheduled;
esperaAtivaUs(PERTURBAR_DENTRO_US);
// Em seguida permanece:
uint32_t t0 = micros();
// Substitua serveDueTask() por esta versão.
void serveDueTask() {
if (!prePerturbUsed && PERTURBAR_ANTES_US > 0 && served >= 3) {
prePerturbUsed = true;
esperaAtivaUs(PERTURBAR_ANTES_US);
}
uint32_t now = micros();
if ((int32_t)(now - nextDue) >= 0) {
uint32_t elapsed = now - nextDue;
uint32_t skipped = elapsed / PERIOD_US;
uint32_t scheduled = nextDue + skipped * PERIOD_US;
discarded += skipped;
nextDue = scheduled + PERIOD_US;
runTask(scheduled);
}
}// Ensaio interno: PERTURBAR_DENTRO_US = 3000, PERTURBAR_ANTES_US = 0 cont n=100 d=0 p=0 dur aq=112 ca=4 sa=4 cr=3132 tmp la=16 in=9996/10004 // Ensaio pré-atendimento: PERTURBAR_DENTRO_US = 0, PERTURBAR_ANTES_US = 35000 cont n=98 d=2 p=0 dur aq=112 ca=4 sa=4 cr=132 tmp la=5016 in=4860/35140
Os tempos exatos variam entre placas e condições. No ensaio interno, `cr` deve aumentar cerca de 3.000 µs, sem que a espera seja atribuída a `aq`, `ca` ou `sa`. No pré-atendimento, espere `d` próximo de 2 e `la` próximo de 5.000 µs. A grade preservada produz um intervalo longo durante o bloqueio e, logo depois, um intervalo curto até a próxima liberação prevista.
Compare a influência da comunicação sem deixar de obter um resumo. Execute duas vezes, sempre com PERTURBAR_DENTRO_US = 0 e PERTURBAR_ANTES_US = 0:
RELATORIOS_PERIODICOS = true: há relatórios durante cinco segundos e um último resumo ao fim.RELATORIOS_PERIODICOS = false: as métricas são acumuladas em silêncio por cinco segundos e só então é emitido um resumo.Em cada mudança, carregue o sketch novamente. A versão silenciosa não torna a comunicação “gratuita”; ela apenas remove os envios durante a janela para comparar seu efeito.
Faça todas estas edições: adicione as declarações globais; em setup(), acrescente a linha que inicializa testEnd; por fim, substitua loop() inteiro. A janela termina após 5 segundos nas duas condições.
// Adicione junto às variáveis globais.
const bool RELATORIOS_PERIODICOS = true;
const uint32_t TEST_WINDOW_US = 5000000UL;
uint32_t testEnd;
bool testEnded = false, finalCaptured = false;
// Em setup(), após: nextReport = now + REPORT_US;
testEnd = now + TEST_WINDOW_US;
// Substitua loop() inteiro por esta versão.
void loop() {
serveDueTask();
uint32_t now = micros();
if (!testEnded && RELATORIOS_PERIODICOS && reportPhase == 0 &&
(int32_t)(now - nextReport) >= 0) {
captureReport();
nextReport = now + REPORT_US;
}
if (!testEnded && (int32_t)(now - testEnd) >= 0) {
testEnded = true;
}
if (testEnded && !finalCaptured && reportPhase == 0) {
captureReport();
finalCaptured = true;
}
if (reportPhase != 0) emitReport();
}// Com RELATORIOS_PERIODICOS = true, após cerca de 5 s: cont n=500 d=0 p=0 dur aq=112 ca=4 sa=4 cr=132 tmp la=36 in=9996/10024 // Com RELATORIOS_PERIODICOS = false, após cerca de 5 s: cont n=500 d=0 p=0 dur aq=112 ca=4 sa=4 cr=132 tmp la=12 in=9996/10004
Os números são representativos, não obrigatórios. A escrita é adiada quando o buffer não tem espaço para uma linha inteira, mas a formatação e os envios ainda ocupam tempo no `loop()`. Compare principalmente `cr`, `la`, `in`, `d` e `p` entre as duas execuções.
É possível que as duas condições deem números parecidos: isso também é um resultado válido. Se a condição periódica aumentar la, o maior in, d ou p, a comunicação está disputando tempo com o próximo atendimento. A duração crítica cr pode permanecer semelhante, porque a emissão ocorre fora de runTask().
Antes de seguir para a validação, restaure PERTURBAR_DENTRO_US = 0, PERTURBAR_ANTES_US = 0 e remova ou desative a janela de teste, voltando ao loop() normal da etapa anterior.
O maior valor medido é uma evidência das condições exercitadas e do tempo do ensaio; não prova um limite garantido para todos os caminhos futuros, interrupções ou usos da comunicação.
Revise o orçamento com a condição relevante mais exigente: duração crítica, agendamento, instrumentação, demais atividades do loop() e comunicação. Preserve uma reserva explícita. Se descartes se repetirem em condições normais, reduza trabalho ou comunicação; reveja o período apenas se banda, dinâmica e atraso aceitável continuarem atendidos.
Qual conclusão sobre a maior duração observada é adequada?
Registre uma conclusão curta: informe qual condição elevou mais cr; qual elevou mais la, d ou os extremos de intervalo; o que ocorreu na comparação serial; e como ajustará a margem. Inclua que as perturbações foram restauradas para zero e a limitação das evidências.
Escreva pelo menos 180 caracteres (0/180).

Passo 9 de 9
Consolide período, orçamento, medições e política de recuperação em um registro técnico conciso e prudente.
Faça uma última execução sem as perturbações artificiais usadas para testar duração ou atraso. Mantenha o mesmo período, montagem e sketch que pretende usar como referência.
Registre as condições que importam: placa usada, alimentação por USB, sinais conectados, período configurado, duração aproximada do ensaio e se o Monitor Serial estava ativo. Então anote os maiores valores observados de duração e latência, os limites dos intervalos reais, descartes e perdas de prazo.
A conclusão deve separar duas afirmações:
Mesmo que descartes e perdas de prazo sejam zero, isso é uma boa evidência para o ensaio realizado — não uma garantia absoluta.

A decisão combina requisito temporal, orçamento revisado, métricas observadas e condições declaradas.
Use este modelo no seu caderno técnico ou em um arquivo local. Preencha com os valores do seu ensaio final.
Prefira valores com unidade. Se ainda não mediu algum valor, registre isso como pendência, não como zero.
Dica
A tarefa é viável nas condições ensaiadas quando o orçamento revisado e as métricas finais deixam margem para operar, e a política de atraso evita recuperação ilimitada. Uma conclusão cuidadosa sempre declara suas condições e limites.
Se a duração, a latência ou as perdas de prazo mostrarem que a margem é insuficiente, não trate descartes como correção permanente. Escolha a ação que ataca a causa:
Depois da mudança, refaça orçamento e medição. Diminuir a frequência de atualização apenas para "parar os atrasos" pode prejudicar o requisito do sinal ou da resposta do sistema.
Exemplo
Seu registro final deve explicar, em poucas linhas: qual período adotou, por que ele é aceitável para a dinâmica, qual margem restou no orçamento, quais foram as métricas medidas e o que acontecerá se houver liberações vencidas. Inclua também uma frase de limite: por exemplo, “não foram observadas perdas neste ensaio; isso não demonstra um pior caso garantido”.
Escreva seu registro final de decisão. Inclua: período e justificativa dinâmica; orçamento com margem; condições e métricas do ensaio final; política para atrasos; e uma limitação explícita da evidência obtida.
Escreva pelo menos 300 caracteres (0/300).
Resumo
Parabéns! Você concluiu: Período de atualização e orçamento de execução
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks