Engenheiro eletricista -
Desenvolvedor de hardware.
Protótipos e projetos.
Desenvolvimento de software de interface.(aguivone@gmail.com)
quarta-feira, 27 de agosto de 2025
Conseguindo melhorar a velocidade dos pinos do ESP32 e ESP8266 - análise de desempenho.
Olá quando se precisa de tempos na escalas de nanosegundos se torna um problema para muitas placas e módulos utilizados no ARDUINO, então se recorre a módulos mais velozes como o ESP32 ou ESP8266. Porem temos a surpresa de mesmo sendo tão velozes não conseguimos acionar de forma pulsada na escala de nanosegundos ou até 20 microssegundos, pois abaixo disso nestes módulos começa a fazer diferenças os pequenos atrasos de tempo nas rotinas de tempo e com a função "digitalWrite".
configuração do módulo, a 240Mhz,logo cada ciclos de máquina levaria 4,16ns, o que :
Vamos a nosso plano de análise com um trecho de código fonte simples, onde apenas vamos ligar de desligar o pino 13(D13) do módulo ESP32, a mesma analise vale para o ESP8266. Note que em vez de colocar pino D0,D1,D2 ... podemos usar os define de sistema BIT0,BIT1, BIT2 ... ou seja não precisa memorizar qual o valor em hexadecimal da posição de cada
pino. porém o tempo será diferente.
Veja o trecho de código:
//demontrando a diferença entre usar digitalWrite e REG_WRITE
voidsetup()
{
pinMode(13, OUTPUT); //pino D13
}
voidloop()
{
digitalWrite(13, HIGH);
delayMicroseconds(1);
digitalWrite(13, LOW);
delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TS_REG, BIT13); // é um define do arduino que vale 0X2000
delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
delayMicroseconds(1);
}
Para o primeiro teste:
//demontrando a diferença entre usar digitalWrite e REG_WRITE
voidsetup()
{
pinMode(13, OUTPUT); //pino D13
}
voidloop()
{
digitalWrite(13, HIGH);
delayMicroseconds(1);
digitalWrite(13, LOW);
delayMicroseconds(1);
/*REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
delayMicroseconds(1);*/
}
Para o segundo teste:
//demontrando a diferença entre usar digitalWrite e REG_WRITE
voidsetup()
{
pinMode(13, OUTPUT); //pino D13
}
voidloop()
{
/*digitalWrite(13, HIGH);
delayMicroseconds(1);
digitalWrite(13, LOW);
delayMicroseconds(1);*/
REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
delayMicroseconds(1);
}
Para o terceiro teste:
//demontrando a diferença entre usar digitalWrite e REG_WRITE
voidsetup()
{
pinMode(13, OUTPUT); //pino D13
}
voidloop()
{
//digitalWrite(13, HIGH);
delayMicroseconds(1);
//digitalWrite(13, LOW);
delayMicroseconds(1);
/*REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
delayMicroseconds(1);*/
}
Para o quarto teste:
//demontrando a diferença entre usar digitalWrite e REG_WRITE
voidsetup()
{
pinMode(13, OUTPUT); //pino D13
}
voidloop()
{
/*digitalWrite(13, HIGH);
delayMicroseconds(1);
digitalWrite(13, LOW);
delayMicroseconds(1);*/
REG_WRITE(GPIO_OUT_W1TS_REG, BIT13);
// delayMicroseconds(1);
REG_WRITE(GPIO_OUT_W1TC_REG, BIT13);
// delayMicroseconds(1);
}
Agora vamos ao resultado dos testes, usando a rotina "delayMicroseconds(1)" :
digitalWrite -> 3,27us em nivel alto e 4,19us em nivel baixo.
REG_WRITE -> 1,54us em nivel alto e 1,54us em nivel baixo.
sem rotinas de tempo :
digitalWrite -> 529ns em nivel alto e 778ns em nivel baixo.
REG_WRITE -> 58ns em nivel alto e 252ns em nivel baixo.
vídeo de demonstração:
Conclusão:
Veja a diferença que tivemos ao usar "REG_WRITE" em vez de "digitalWrite", dando até 10x
mais rapido em nivel alto e 3X mais rapido em nivel baixo, claro que se pode descer um
pouco mais e fazer em assembly conseguindo algo proximo dos 4,16ns esperado, porém fica
o alerta para aplicações criticas. um dos motivos dessas diferenças entre nível alto e baixo
é devido aos codigos que rodam por baixo dessas funções.
Espero que possa ajudar alguém essa simples e importante análise.
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!