Neste tutorial vamos mostrar como usar a memória EEPROM interna do Arduino. A EEPROM está presente em todas as versões do Arduino, mas muitas vezes a falta de conhecimento de sua existência é contornada com a instalação de memórias EEPROM externas ou mesmo de um cartão de memória SD de vários gibabytes para armazenar algumas poucas variáveis ou dados.
Uma EEPROM (de Electrically-Erasable Programmable Read-Only Memory) é um tipo de memória que pode armazenar valores que serão retidos mesmo quando a energia é desligada e pode ser programada e apagada várias vezes, eletricamente. Pode ser lida um número ilimitado de vezes, mas só pode ser apagada e programada um número limitado de vezes, que varia normalmente entre 100.000 e 1 milhão.
A quantidade de memória EEPROM presente em um Arduino varia conforme o microcontrolador instalado na placa: 1024 bytes para o ATmega328, 512 bytes no ATmega168 e ATmega8, e 4 KB (4096 bytes) sobre o ATmega1280 e ATmega2560.
Vamos usar a biblioteca EEPROM para ler e escrever valores na memória EEPROM, esta biblioteca já vem instalada na IDE e existem três exemplos de uso na aba File/Examples/EEPROM.
Para usar esta função basta incluir a biblioteca no início do sketch desta forma:
#include <EEPROM.h>
Uma vez que a biblioteca é incluída no programa, um objeto EEPROM está disponível para o acesso a memória. A biblioteca fornece comandos para ler e escrever dados na memória. A biblioteca EEPROM requer que você especifique o endereço de memória que você deseja ler ou escrever. Isto significa que você precisa se manter a par de onde cada valor é escrito de forma que quando você for ler o valor, acesse a partir do endereço correto.
Para escrever um valor na memória, use:
EEPROM.write(address, value);
Onde:
address – posição da memória que será escrito, é um inteiro entre 0 e 1023 (UNO);
value - valor a ser armazenado inteiro entre 0 e 255 (um único byte).
Agora vamos entender o exemplo que está disponível na IDE do arduino para a utilização deste comando, primeiro devemos montar um potenciômetro na entrada 0 do arduino conforme mostrado na figura abaixo, em seguida devemos fazer o upload do código do sketch mostrado mais abaixo para o arduino.
Este exemplo simplesmente salva periodicamente na EEPROM os valores lidos na entrada analógica para que possam ser acessados posteriormente.
Código exemplo para o comando EEPROM.Write:
/* * Exemplo EEPROM Write * Armazena valores lidos na entrada analógica na EEPROM. * Estes valores permanecerão guardados mesmo que a placa * seja desligada e podem ser recuperados posteriormente pelo próximo sketch */ #include <EEPROM.h> // incluir a biblioteca int addr = 0; // endereço de escrita na memória void setup() { } void loop() { // é preciso dividir val por 4 porque o range da entrada analógica // vai de 0 a 1023 e cada byte da EEPROM só pode guardar // valores compreendidos entre 0 e 255. int val = analogRead(0) / 4; // escreve o valor de val na EEPROM no endereço selecionado em addr. // este valor permanecerá guardado mesmo // que placa seja desligada da fonte de alimentação EEPROM.write(addr, val); // avança para o próximo endereço indo até o byte 512 da // EEPROM, quando então retorna para o byte 0. addr = addr + 1; if (addr == 512) addr = 0; delay(100); }
Este sketch começa com a inclusão da biblioteca EEPROM e da declaração da variável addr que define o endereço da EPROM a ser gravado. Em seguida é iniciado o loop principal com a realização da leitura do valor presente na entrada analógica 0 divido por 4 que é salvo em val. O valor de val é escrito no endereço da EEPROM indicado por addr. Em seguida o endereço é incrementado em uma unidade e se for igual a 512 é zerado. O programa aguarda por 100ms para então repetir indefinidamente o loop principal.
Para ler uma determinada posição de memória, use:
value = EEPROM.read(address);
Onde:
address – posição da memória que será lido, é um inteiro entre 0 e 1023 (UNO);
value - valor do endereço da EEPROM é um inteiro entre 0 e 255 (um único byte).
Abaixo vemos o exemplo da IDE do arduino para a utilização deste comando, não é necessário alterar o circuito montado para o exemplo anterior visto que este sketch usa apenas o canal serial do arduino através do cabo USB. Faça o upload do sketch abaixo para o arduino e abra o monitor serial, voce verá que os valores salvos na EEPROM pelo sketch anterior serão mostrados na tela do computador.
Código exemplo para o comando EEPROM.Read:
/* * EEPROM Read * Le o valor de cada byte da EEPROM e imprime na tela do computador. * o código deste exemplo é de domíno público */ #include <EEPROM.h> // incluir a biblioteca // inicia lendo apartir do primeiro byte (endereço 0) da EEPROM int address = 0; // endereço de escrita na memória byte value; // valor lido da EEPROM void setup() { Serial.begin(9600); // inicializa o canal de comunicação serial } void loop() { // lê o byte no endereço atual da EEPROM value = EEPROM.read(address); // envia o valor lido para o computador pela porta serial Serial.print(address); Serial.print("\t"); Serial.print(value, DEC); Serial.println(); // avança para o próximo endereço da EEPROM address = address + 1; // quando atingir o endereço 512 retorna // para o endereço 0 if (address == 512) address = 0; delay(500); }
Estes exemplos foram feitos para rodar em qualquer versão do arduino, por isso que só foram escritos ou lidos os endereços de 0 a 511 da EEPROM, se voce quiser pode ficar a vontade e tentar alterar o sketch para ler e escrever em todos endereços disponiveis na sua placa.
Agora voce pode estar se perguntando:
“Existe alguma forma de armazenar um valor maior que 255 na EEPROM?”
A resposta é sim e é algo fácil de se fazer, usando os comandos para a conversão de valores de 16 ou de 32 bits em bytes.
loByte = highByte(val);
hiByte = lowByte(val);
Onde:
val - qualquer tipo de variavel
loByte - byte com a parte mais baixa de val
hiByte - byte com a parte mais alta de val
Vamos agora alterar o primeiro programa de forma a salvarmos os valores lidos da entrada analógica sem ter dividir o valor por 4 de forma a não perder a resolução da medida.
/* * Exemplo EEPROM Write * Armazena valores lidos na entrada analógica na EEPROM. * Estes valores permanecerão guardados mesmo que a placa * seja desligada e podem ser recuperados posteriormente pelo próximo sketch */ #include <EEPROM.h> // incluir a biblioteca int addr = 0; // endereço de escrita na memória void setup() { } void loop() { // lê o valor na entrada analógica e guarda em val int val = analogRead(0); // divide val que é um inteiro de 16 bits em dois bytes byte hiByte = highByte(val); byte loByte = lowByte(val); // escreve o byte mais significativo de val na EEPROM no endereço selecionado em addr EEPROM.write(addr, hiByte); // escreve o byte menos significativo de val na EEPROM no endereço selecionado em addr+1. EEPROM.write(addr+1, loByte); // avança para o próximo endereço pulando de 2 em 2, pois estamos armazenando // valores com dois bytes cada até alcançar o byte 512 da // EEPROM, quando então retorna para o byte 0. addr = addr + 2; if (addr == 512) addr = 0; delay(100); }
Agora devemos alterar o segundo sketch para poder recuperar os valores salvos na EEPROM, para isso usaremos a função word que converte dois bytes em um inteiro de 16bits. A sintaxe deste comando é mostrada abaixo.
value = word(x)
value = word(h, l)
value = word(h, l)
Onde:
value - uma word
x - uma variável de qualquer tipo
h - a parte alta de uma word
l - a parte baixa de uma word
/* * EEPROM Read * Le o valor de cada byte da EEPROM e imprime na tela do computador. * o código deste exemplo é de domíno público */ #include <EEPROM.h> // incluir a biblioteca // inicia lendo apartir do primeiro byte (endereço 0) da EEPROM int address = 0; // endereço de escrita na memória byte value; // valor lido da EEPROM void setup() { Serial.begin(9600); // inicializa o canal de comunicação serial } void loop() { // lê o byte no endereço atual da EEPROM byte hiByte = EEPROM.read(address); byte lowByte = EEPROM.read(address +1); value = word(hiByte, lowByte); // envia o valor lido para o computador pela porta serial Serial.print(address); Serial.print("\t"); Serial.print(value, DEC); Serial.println(); // avança para o próximo endereço da EEPROM address = address + 2; // quando atingir o endereço 512 retorna // para o endereço 0 if (address == 512) address = 0; delay(500); }
Para a utilização da EEPROM, é aconselhável sempre fazer um mapa das variáveis que estão sendo guardadas e os seus respectivos endereços, para assegurar que nenhum endereço seja usado por mais de uma variavel, e que os valores de bytes múltiplos não sobresecrevam outras informações.
É isso, a EEPROM é um recurso muito útil e fácil de usar no Arduino, porém relativamente pouco utilizado.
Para limpar a memoria da EEPROM basta utilizar o seguinte código:
/* * * Limpa a memória da EEPROM. * */ #include <EEPROM.h> void setup() { // Escreve " 0 " em todos os bytes da EEPROM // (neste caso como e um arduino mega sao 512 bytes) for (int i = 0; i < 512; i++) EEPROM.write(i, 0); // O LED acende quando a memoria estiver limpa digitalWrite(13, HIGH); } void loop() { }
Referências:
Margolis, Michael. Arduino Cookbook. Editora O’REILLY, 2011. Capítulo 18.
Nenhum comentário:
Postar um comentário