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
void setup()
{
  pinMode(13, OUTPUT); //pino D13
}
void loop()
{
  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
void setup()
{
  pinMode(13, OUTPUT); //pino D13
}
void loop()
{
  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
void setup()
{
  pinMode(13, OUTPUT); //pino D13
}
void loop()
{
  /*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
void setup()
{
  pinMode(13, OUTPUT); //pino D13
}
void loop()
{
  //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
void setup()
{
  pinMode(13, OUTPUT); //pino D13
}
void loop()
{
  /*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!