Postagem em destaque

Controle PID de Potência em Corrente Alternada - Arduino e TRIAC - Parte I

Este post é o primeiro de uma série de seis que escrevi tratando de controle de potência e PID (controle proporcional, integral e derivativo...

quarta-feira, 30 de outubro de 2013

Expandindo a memória do Arduino I

A memória do Arduino é curta. O certo seria inclusive escrever "as memórias", já que existe mais de um tipo de memória:

Memória flash: é a memória que armazena os nossos programas. O Arduino pode ser desligado e o programa não se perde. A memória disponível para os nossos programas é um pouco menor do que a disponibilizada pelo processador do Arduino. O motivo é que nessa memória existe também o bootloader do Arduino, que é um programa que vem gravado nessa memória para receber o nosso programa enviado pela serial. Mas tergiverso, voltemos às memórias.

Memória SRAM: é um tipo de memória que serve para guardar as nossas variáveis. Ela é volátil, ou seja, quando a energia é cortada ou a paquinha é resetada, baubau, perdeu, playboy.

Memória EEPROM: é uma memória não volátil que serve para guardar dados.

Nos dois Arduinos mais comuns, Uno e Mega, temos:


Memória Uno  Mega
Flash 32k 256k
SRAM 2k 8k
EEPROM 1k 4k

Ou seja, é um recurso escasso.

Para aumentar o tamanho da memória para código não há recurso. Pode-se otimizar o seu uso, programando de maneira mais minimalista. No caso da memória para dados, aí existem algumas alternativas. A que a gente mais usa é o cartão SD, já que existem alguns breaks que são fáceis de encontrar e usar. Tem também alguns shields, como os de MP3 e Ethernet, que costumam ter suporte a cartões SD e MiniSD.

Uma outra alternativa é usar chips EEPROM, que são muito baratos e estão ficando fáceis de achar (no Mercado Livre tem). Porém não se acha muita coisa na net sobre o seu uso, por isso resolvi escrever a respeito.

O chip que estou usando é o Atmel AT24C512, mas tem outros fabricantes que fornecem equivalentes.

Ele é um chip de 512k bits de memória não volátil, o que significa que ele tem 64k bytes de memória EEPROM. Para a gente se comunicar com ele usa-se a interface I2C, que é implementada pela lib wire.h. Uma coisa interessante é que vc pode ligar até quatro deles em cascata (ou em "cadeia de margaridas", como dizem nossos irmãos lá do norte). Aí eles vão funcionar como uma só memória de 256k bytes.

Abaixo, uma imagem do bicho já devidamente conectado ao Arduino:

Dá prá ver que ele é bem pequeno, desses de oito pinos. As conexões são as seguintes:

Pinos 1* a 4: GND
Pino  5: SDA - conectado à porta A4 do Arduino
Pino  6: SCL - conectado à porta A5 do Arduino
Pino  7: GND
Pino  8: Vcc - pode ser conectado aos pinos 3V3 ou 5V do Arduino.

Para ler e gravar no bicho temos a lib EEPROM24LC256_512.h, que pode ser baixada aqui.

Eu peguei um exemplo que vem com a lib e dei uma simplificada (achei-o um tanto confuso).

Abaixo vcs podem vê-lo. Divirtam-se!




#include "Wire.h"
#include "EEPROM24LC256_512.h"

unsigned int randomNum=0;
 
//define eeprom chip (1 per chip)
EEPROM256_512 mem;
 
void test512ByteBounds()
{
  byte d;
  mem.writeByte(0, 0b10111101);
  d=mem.readByte(0);
   
  Serial.print(" Address: 0");
  Serial.print(" Read Data: "); Serial.println(d, BIN);
      
  mem.writeByte(65535, 0b10111101);
  d=mem.readByte(65535);
   
  Serial.print(" Address: 65535");
  Serial.print(" Read Data: "); Serial.println(d, BIN);
}
 
void test512ByteSequence()
{
    int i=0;
    byte d;
   //get 512 random bytes... write to them.  read them
   Serial.println("Testing Corner Cases");
   test512ByteBounds();
    
   randomSeed(analogRead(0));
   Serial.println("Testing Byte Sequence (24LC512) - 512 random bytes");
   for(i=0; i<512;i++)
   {
     randomNum = random(0,65535);//get random byte number
     mem.writeByte(randomNum, 0b10111101);
     d=mem.readByte(randomNum);
     Serial.print("Seq: "); Serial.print(i);
     Serial.print(" Address: "); Serial.print(randomNum);
     Serial.print(" Read Data: "); Serial.println(d, BIN);
   }
}
 
void Test512()
{
  //print page size
  Serial.print("24LC512 Page Size: ");
  Serial.println(mem.getPageSize());
   
  //exercise byte write/read
  test512ByteSequence();
}
 
void setup() {
  Wire.begin();
  mem.begin(0,0);
  Serial.begin(9600);
  Test512();
}
 
void loop() {}