[DICA] String - Otimização de sketchs com a macro F()

Percebi aqui no fórum do Garagem vários colegas relatando problemas de memória causados pelo uso excessivo de variáveis do tipo String. Esse tipo de problema ocorre com frequência em aplicações que envolvem a criação de páginas HTML que são montadas através de concatenação, mas essa dica se aplica a qualquer tipo de aplicação que trabalha muito com Strings.

Para entender melhor essa dica, é preciso explicar como está organizada a memória do Arduino:

Flash memory --> Onde o sketch é armazenado
SRAM --> Armazenamento de variáveis
EEPROM --> Informações de longo prazo (não voláteis)

A regra é: Precisamos economizar a memória SRAM.

Veja o seguinte comando:

Serial.print("Aguarde 1 minuto");
delay(1000);

A String literal "Aguarde 1 minuto" vai ocupar preciosos 17 bytes na memória SRAM para um valor constante que nunca mais vai ser usado. Isso é péssimo!

Para resolver esse problema, use a macro F().
Essa macro vai fazer com que a String seja armazenada na memória Flash ao invés da SRAM.

Substitua o comando acima por:

Serial.print(F("Aguarde 1 minuto"));
delay(1000);

Veja abaixo o resultado da compilação dos exemplos acima em NodeMCU ESP8266:

Sem F()
O sketch usa 221.401 bytes (21%) de espaço de armazenamento para programas. O máximo são 1.044.464 bytes.
Variáveis globais usam 31.336 bytes (38%) de memória dinâmica, deixando 50.584 bytes para variáveis locais. O máximo são 81.920 bytes.

Com F()
O sketch usa 221.409 bytes (21%) de espaço de armazenamento para programas. O máximo são 1.044.464 bytes.
Variáveis globais usam 31.304 bytes (38%) de memória dinâmica, deixando 50.616 bytes para variáveis locais. O máximo são 81.920 bytes.

Vejam que o espaço para o programa diminui, aumentando o espaço para as variáveis, o que é muito bom!

Então, ao atribuir um valor para uma variável String, ao invés de fazer assim:
client.print("<HTML><BODY>");
Faça:
client.print( F("<HTML><BODY>"));

Veja mais em:
http://playground.arduino.cc/Learning/Memory
https://learn.adafruit.com/memories-of-an-arduino/optimizing-sram

Comentários são bem-vindos...

Exibições: 1212

Responder esta

Respostas a este tópico

Bom dia José Augusto.

Excelente dica, principalmente para quem não domina muito programação, como é o meu caso.

Valeu !

Olá Bernardo!

Nós que trabalhamos com pequenos dispositivos temos que empregar todas as técnicas para economizar memória, até mesmo por motivos de segurança, pois os crashes de memória produzem comportamentos inesperados.

Lembro que você estava em um projeto com a ATtiny, cuja memória é menor ainda do que do Arduino UNO: 512 SRAM . É preciso fazer mágica nesses casos...

Olá José Augusto!

Cara, até hj eu não tinha a menor idéia do que era esse F( )....

Eu só sabia que isso tinha me salvado um projeto, justamente por causa da sobrecarga da SRAM. O aparelho que estava desenvolvendo precisava escrever várias coisas no display, intruções ao usuário, e rapidinho dava estouro da memória e eu ficava sem conseguir gravar os dados lidos. Durante o processo de "bateção de cabeça" para resolver o problema, encontrei alguém comentando sobre essa macro, mas apenas falava para coloca-la, sem explicar o que era ela!

Agora, finalmente, entendi o que é essa "função" (como eu chamava antigamente).....

Muito obrigado pela explicação!!!

Olá Renato!

Interessante o seu depoimento. Um resultado prático.

A F() é uma macro porque na verdade é um declaração define na lib WString.h

Sua principal aplicação é em constantes Strings que foi o seu caso.

Isso foi em que ano?

Opa Jose!

Isso foi na metade do ano passado. Eu estava desenvolvendo um pequeno aparelho para ajudar na calibração de aparelhos de medição de pressão arterial. Na rotina precisava mandar vários comandos para o display e depois ler um sensor de pressão e gravar os dados no cartao SD para análise posterior. Eu percebia que na metade do processo o arduino parava de gravar as leituras, tipo, grava até a 5ª leitura de as demais já não gravava. Depois de usar uma rotinazinha para  testar a quantidade de memória ainda disponível, ví que o problema era memoria realmente. Aí fui atras de algo para resolver e acabei achando essa macro. Mas, no site em que achei não explicava muito bem o que era e o que fazia, por isso achei muito legal vc vir e explicar aqui!

O que me importou mesmo na época é que consegui salvar meu projeto! hehehehehe

obrigado!

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço