Tradutor

quarta-feira, 13 de março de 2013

Aumente a memória de seu arduino



Arduino é uma placa de interface entre o computador e circuitos eletrônicos porem possui limitações de portas, velocidade e tamanho de memória fazendo com que programas mais complexos não caibam dentro da placa. Atualmente o Arduino UNO é baseado no ATMega328 que utiliza 32kB de memória flash onde 0,5KB é destinado para o bootloader, 2KB de memória SRAM e 1KB de memória EPROM.


Para que possamos entender melhor cada memória vamos a alguns termos:



- Memória Flash - é uma memória do tipo não volátil, o que significa que não precisa de energia para manter as informações armazenadas, oferece um tempo de acesso rápido, embora não tão rápido como a memória volátil DRAM ou SRAM, são extremamente duráveis, sendo capaz de resistir a uma pressão intensa, variações extremas de temperatura, e até mesmo imersão em água.



- Memória SRAM (Static Random Access Memory) - é um tipo de memória de acesso aleatório que mantém os dados armazenados desde que seja mantida sua alimentação, não precisando que as células que armazenam os bits sejam refrescadas (atualizadas de tempo em tempo), como é o caso das memórias DRAM, ou seja, enquanto existir energia os dados serão armazenados. Embora sejam mais caras e ocupem menos espaço, quando comparadas às DRAM, possuem a vantagem de serem bem mais rápidas.



- Memória EPROM (erasable programmable read-only memory) - é um tipo de chip de memória de computador que mantém seus dados quando a energia é desligada, geralmente utilizando para armazenar seus programas.  Existe a EEPROM que utiliza a eletricidade para gravar e apagar os dados da memória.


Para aumentar a capacidade da placa podemos utilizar chips extras de memória como o chip AT24C com dois modelos, sendo o primeiro com 256kb (32K bytes) e o segundo com 512KB (64K bytes), este módulo utiliza conexão I2C bus para conectar ao Arduino, para comunicação da EEPROM recomendamos uma interface Arduino-I2C-COM-Cable, Arduino Special Sensor Shield V4.0, ou através de cabos.


Este módulo de armazenamento é baseado no chip AT24C que através do I2C pode endereçar 0x50 e os últimos três endereços de memória podem ser setados de acordo com as necessidades. Ou seja, devemos setar pelo menos três endereços quando utilizado pela primeira vez através das quatro posições do DIP switch. Coloque a alavanca para cima e corresponderá a 1 e coloque a alavanca para baixo e corresponderá a 0, movendo os endereços A0, A1, A2 para cima corresponderá a  0x57, mas movendo os endereços A0, A1, A2 para baixo corresponderá a 0x50.



Se você usar o Arduino Sensor Shield preste atenção à posição do jumper IIC/COM que deve estar setada como IIC porque precisaremos usar I2C para conecção.
  

Observe o código abaixo:


#include <Wire.h>
#define EEPROM_ADDR 0x50        // Endereço do I2C Buss para 24LC256 256K EEPROM

void setup()
{
  Wire.begin();                        // Acessa I2C bus (endereço opcional para master)
  Serial.begin(9600);

  // TESTE PARA CADA FUNÇÃO COMEÇA AQUI 

  Serial.println("Writing Test:");
  for (int i=0; i<20; i++){            // loop dos primeiros 20 slots
    i2c_eeprom_write_byte(EEPROM_ADDR,i,i+65);   // escreve endereço + 65 A ou 97 a
    Serial.print(". ");
    delay(10);                         // É PRECISO ESTE ATRASO!
  }
  Serial.println("");
  delay(500);

  Serial.println("Reading Test:");
  for (int i=0; i<20; i++){            // loop dos primeiros slots
    Serial.print(i2c_eeprom_read_byte(EEPROM_ADDR, i),BYTE);
    Serial.print(" ");
  }

  // Configura página de teste . . .
byte PageData[30];                   // Vetor que irá conter os dados de teste para um página  

byte PageRead[30];                   // Vetor que irá conter o resultado dos dados para um página 
for (int i=0; i<30; i++){            // Zera os dois vetores para o próximo teste 
    PageData[i] = 0;
    PageRead[i] = 0;
  }
  Serial.println("");
  for (int i=0; i<30; i++) PageData[i] = i+33;  // preenche o vetor para o proximo teste char 33 = !

  Serial.println("Writing Page Test:");
  i2c_eeprom_write_page(EEPROM_ADDR, 100, PageData, 28 ); // máximo de 28 bytes/page

  Serial.println("Reading Page Test:");
  i2c_eeprom_read_buffer( EEPROM_ADDR, 100, PageRead, 28);
  for (int i=0; i<28; i++){
    Serial.print(PageRead[i],BYTE);    // mostra o vetor read
    Serial.print(" ");
  }
}

void loop()
{
}

void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data )
{
  int rdata = data;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));    // Endereça o Byte como alto
  Wire.send((int)(eeaddress & 0xFF));  // Endereça o Byte como baixo
  Wire.send(rdata);
  Wire.endTransmission();
}

// Endereça a pagina de endereço, 6-bit (63).
// Mas o dado pode ser no máximo 28bytes, porque a biblioteca Wire tem um buffer de 32 bytes
 

void i2c_eeprom_write_page( int deviceaddress, unsigned int eeaddresspage, byte* data, byte length )
{
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddresspage >> 8)); // Endereça o Byte como alto
  Wire.send((int)(eeaddresspage & 0xFF)); // Endereça o Byte como baixo
  byte c;
  for ( c = 0; c < length; c++)
    Wire.send(data[c]);
  Wire.endTransmission();
  delay(10);                           // Precisa de um pouco de atraso
}

byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress )
{
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));    // Endereça o Byte como alto
  Wire.send((int)(eeaddress & 0xFF));  // Endereça o Byte como baixo
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

// Não deve ler mais que 28 bytes por vez!
void i2c_eeprom_read_buffer( int deviceaddress, unsigned int eeaddress, byte *buffer, int length )
{
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));    // Endereça o Byte como alto
  Wire.send((int)(eeaddress & 0xFF));  // Endereça o Byte como baixo
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,length);
  //int c = 0;
  for ( int c = 0; c < length; c++ )
    if (Wire.available()) buffer[c] = Wire.receive();
}
Veja o resultado abaixo:


Conclusão:


Com este módulo é possível aumentar a memória do Arduino, com isso sendo possível desenvolver programas mais complexos e com mais funções, sendo uma ótima alternativa para seus projetos.