Neste Aula vamos falar da memória EEPROM do Arduino.
Mostraremos como gravar e apagar informações na EEPROM.
Ao fim e´ apresentado um projeto que permite gravar uma senha e testa-la. Mas apenas três tentativas são permitidas. E´ uma espécie de jogo do acerte a senha que digitei.
Vamos lá ?
Inicialmente devemos tomar conhecimento que exitem 3 tipos de memórias para gravação de dados
Sendo que cada uma tem um comportamento diferente seja em quantidade de gravação ou se e´ volátil ou não.
O Tabala abaixo informa a relação entre os tipos de memória disponível no Atmega328 e o seu tamanho:
MODELO: Flash EEPROM RAM
ATmega328 32KBytes 1KBytes 2KBytes
Veja também o diagrama de blocos abaixo que mostra como essas memórias se relacionam internamente no chip do microcontrolador ATMEGA328 usado no Arduino:
A memoria que gravamos o código(void loop e setup) no arduino é a FASH.
A memoria EEPROM e´ bem menor que as demais, mas possui propriedades singulares!
Dentre elas: permitir um dado ser gravado quando o programa está rodando e operando. Outra vantagem e´que mesmo que o arduino seja desligado da energia o dado(gravado) não se perde. Por isso a memória EEPROM é uma memoria: não volátil.
Qual a vantagem disso? Imagine que você tenha um aparelho que precisa guardar uma senha mas se alguém esquecer essa senha? Como podemos gravar uma nova?
Pegar o Cabo USB ligar o PC e abrir a IDE do arduino procurar o código e gravar tudo novamente? Seria inviável não?
Para resolver esse problema usamos a memória EEPROM.
O outro ponto positivo é permitir 100mil ciclos gravações(apaga/escreve). Isso pode ser muito mas a depender do que for fazer pode ser limitado. E´preciso saber aplicar corretamente.
Como ninguém costuma esquecer 100mil vezes a senha do alarme de casa essa aplicação(guardar senhas) e´ viável.
Então vamos entender melhor como tudo funciona:
Bem... como que essa memória se comporta?
Inicialmente vamos imaginar "quadradinhos" que podemos chamar de casa.
Agora imaginemos uma rua repleta de casas e cada casa guarda um dado(informação).
Veja a imagem abaixo:
Veja que temos os "quadradinhos".Imagine que essa barra horizontal seja uma rua e cada "quadradinho" seja uma casa.
A cada 8 quadrados(de 0 a 7) teremos 1byte.
O Quadradinho e´ chamado de bit e cada bit(casa) aceita apenas 2 valores (0 ou 1).
E´ aqui que entram os números binários.
As máquinas operam com 0 ou 1 que representa nível lógico baixo (0V) ou nível lógico alto(que pode ser 1.8V, 3.3V ou 5V, normalmente).Agora... Digamos que temos apenas um quadrado ou 1bit.
Como cada casa aceita(0 ou 1) poderíamos fazer combinações neste quadrado assim:
0 que e´o valor "0" em decimal
1 que e´o valor "1" em decimal
Agora com dois quadrados ou 2bits.
0 0 que e´o valor "0" em decimal
0 1 que e´o valor "1" em decimal
1 0 que e´o valor "2" em decimal
1 1 que e´o valor "3" em decimal
Perceba que podemos representar números apenas combinando Zero(0) e Um(1). E quanto maior o número de casas(bits) maior e´a quantidade de números em decimal que podemos representar.
É por isso que 1byte representa valores de 0 a 255 num total de 256 números. E também por isso que os valores guardados na memoria EEPROM do arduino não podem ser maiores que 255. Caso queira seria preciso usar mais bits e esse e´ um tema outra aula.
Veja uma simulação de como isso ocorre em 1byte e seus 8 bits para representar números(valor) adicionados:
A memória EEPROM tem um espaço de 1Kbyte. Sendo 1Kbyte=1024bytes
Logo temos 1024bytes disponíveis no Atmega328. Como pode ser visto na tabela abaixo:
512 bytes -------------------- ATmega168 e ATmega8
1024 bytes ------------------- ATmega328
4 KB (4096 bytes) ----------- ATmega1280 e ATmega2560
E com 1024bytes podemos escrever quantos números em decimal?
Logicamente 1024 valores e cada um pode variar de 0 a 255.
Sendo assim, vamos praticar e executar alguns códigos.
1- Gravando valores na EEPROM:
Execute o código abaixo:
Temos inicialmente que chamar a biblioteca EEPROM.h que é a responsável por fornecer as funções que permitem trabalhar com esta memória;
A função que escreve na memora e´chamada de EEPROM.write(endereço,valor );
Entre os "( )" devemos informar dois dados o endereço da memoria e o valor de um dado a ser gravado.
E o que e´ o endereço?
Vamos voltar ao exemplo da rua que foi ilustrado anteriormente.
Imaginemos a rua com varias casas. Agora se pergunte: Como o carteiro chega a determinada casa e entrega uma carta?
Com o endereço na porta de cada casa não e´ verdade?O mesmo acontece nas memórias.
Temos um dado que queremos gravar(que seria a carta) e temos o endereço na "porta" de cada memoria.
Sendo assim a memoria eeprom no atmega328, como vimos, tem 1024 endereços disponíveis para guardar dados. São eles: endereço: 0,1,2,3,4,5...1022,1023.
Logo: EEPROM.write(0,1 ); informa que o valor "1" deve ser guardado no espeço de memoria(casa ou byte) de endereço "0". E assim vai ate´o endereço 1023. Ou seja de (de 0 a 1023)
OBS: caso esteja usando um atmega8 o número máximo de endereços muda para 511(de 0 a 511)
2- Lendo os valores Gravados:
Agora após ter executado o Código 1 os dados estão gravados e como os dados não se perdem você pode retirar a alimentação do arduino por no armário e deixar por meses, anos, décadas.
Bem e como podemos ler essa informação?
Para isso execute o Código-2 abaixo:
Baixe o Código-2 e execute no Arduino: BAIXAR Código
Neste usaremos a Serial Monitor para ver os valores guardados por isso chamamos a função Serial.begin(9600);
Ela permite usar as funções: Serial.print("digite um texto ");
e Serial.println( dado,DEC); onde: "dado" e´ o que deseja imprimir na tela e DEC e´ o tipo que deve mostrar em decimal(DEC) ou biário(BIN)
O "ln" da função Serial.println(); informa que deve pular uma linha. E´ como o " /n " na programação C.
E a função que mostra o valor que se encontra em determinado endereço e´: EEPROM.read(endereço)
Ao fim pula-se uma linha e aguarda 2s e uma nova leitura e´ feita.
Estude o código linha por linha. Tente fazer modificações e ver o que acontece. ok?
3- PROJETO:
Para aprofundar os conhecimentos vamos apresentar um projeto que permite gravar uma senha e verifica-la penas três vezes. E´ uma especie de jogo do acerte a senha que digitei.
Usaremos 5 botoes, 3 Leds e 3 resistores(pode ser de 300R a 1k) para esse projeto.
O código apresenta uma complexidade bem maior que a dos exemplos anteriores. Recomenda-se um bom entendimento dos temas: Funções, Variáveis Globais e Locais e Resistores de pull-up internos. Para uma fácil compreensão de todo o código.
O arduino modelo NANO será adotado para exemplificar como é fácil o seu uso. Entretanto os modelos, Duemila, UNO, MEGA e outros são perfeitamente compatíveis com esse projeto.
Monte o circuito na protoboard como visto abaixo:
Clicar na imagem para ampliar
Veja como deve ficar no modelo NANO :
Veja vídeo do comportamento do projeto:
Execute o codigo abaixo:
Baixe o Código-3 e execute no Arduino: BAIXAR Código
4- Entendendo o Código do Projeto:
Vamos entender um pouco como funciona o código?
Tudo está dividido em 4 etapas básicas numeradas por: 0 , 1, 2, 3 no void LOOP
Estas etapas chamam funções que realizam tarefas.
Vamos então ao entendimento de cada etapa:
Etapa de Número 0:
//0- faz uma constante varredura dos botões. E para quando algum for ativo. while(val==0) val = varre_bot();
O arduino fica testando cada botão numa velocidade bem grande. A função que faz isso é a varre_bot(); . Assim quando um botão é apertado a varredura para e a variável val assume o valor referente ao botão, que pode ser de 1 a 5, pois trabalharemos com senhas de 1 a 5.
Etapa de Número 1:
byte test= testa_bot(); //se botão foi solto test=0. E test=1 de ficar + de 2 seg.
Nesta a função testa_bot(); retorna 0 ou 1 para a variável test . A ideia e´ que após perceber que um botão foi apertado testa se ele foi solto e conta o tempo que ele ficou apertado. Se ficou por próximo de 2s apertado então deve retornar "1" e isso informa que deve-se ativar a gravação de nova senha.
Caso tenha sido por menos de 2s retorna "0".
Etapa de Número 2:
if (test!=0||escrever==1){ //situação em que o botão ficou muito tempo apertado //entra em modo de gravação if(escrever==0){ digitalWrite(9, LOW); //apaga leds digitalWrite(10,LOW); digitalWrite(11,LOW); pisca_led(13,6,300); //pisca_led(pin,n,t) pin= pino a ser ligado n= numero de repetições e t= o tempo do delay escrever=1; // ativa modo de gravação dos 5 digitos. } else{ new_key(val); //chama gravaçao de senha } }
Nesta e´ feito um teste para verificar se a variável test esta´em "1". E caso afirmativo executa a tarefa de gravar uma nova senha.
Também verifica se a variável escrever é "1" . E caso afirmativo executa a atarefa de gravar nova senha.
escrever e´ a variável que informa que está no modo de gravação de uma senha nova. Ela só retorna a 0 quando os 5 números da senha forem digitados.
A função new_key(val); é a que faz a gravação da senha na eeprom. Ela recebe o valor do botão apertado que é a variável val e grava esse valor.
Etapa de Número 3:
//3- comparação de senha digitada
else
if(test!=1){ //botao foi solto test=0;
char k= testa_key(val); //faz teste de senha
if (k!=0) // nao faz os demais testes se nao tiver recebido os 5valores da senha
{
if(k==1) // senha errada
w++; //incrementa w para informar numero de tentativas erradas. Maximo permitido de 3
else
if(k==2){ // informa que senha foi a correta e faz leds piscarem
vitoria_LED();
}
conta_led(); // conta numero de erros de senha. Após 3 tentativas desliga o arduino
}
}
Nesta o teste da senha e´ feito com a função testa_key(val); retornando 0,1 ou 2 para a variável k
Também é feito a contagem do número de erros. Caso tenha-se chegado a 3 erros o arduino e´ travado e e´preciso reativa-lo com o botão de RESET.
Comentários e recomendações:
Perceba que o void loop e´ relativamente pequeno e basicamente chama funções que fazem algo. Assim para o entendimento do todo é interessante o estudo de cada função.
Observe os valores que retornam e que são incrementados em cada uma.
5 comentários:
Muito bom e muito descritivo o tutorial.!
Parabéns
parebens pela iniciativa, otimo
muito bem explicado tinha algumas
duvidas : Joseph
sua inteligencia esta em void loop
Olá, gostaria de saber se na EEPROM já existem valores pré-definidos ex: 0, e estes valores são sobre escritos com a função EEPROM.write(), ou se no endereço da memória existe um espaço vazio com um /0 e este é sobre escrito ?
não consigo baixar as etapas para concluir o projeto!
Postar um comentário