LusoRobótica - Robótica em Português

Robótica => Tutoriais => Tópico iniciado por: tr3s em 26 de Janeiro de 2009, 14:24

Título: Arduino + EEPROM i2c
Enviado por: tr3s em 26 de Janeiro de 2009, 14:24
Hi,

E que tal falar sobre EEPROMs?

Ora bem, quase todos devem saber o que são e o jeitão que dão quando começamos a ficar sem espaço no nosso microcontrolador e temos a necessidade migrar dados, ou então quando queremos fazer muitos registos e os míseros bytes de memória que o nosso micro tem não são suficientes.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fwww.sparkfun.com%2Fcommerce%2Fimages%2Fproducts%2FEEPROM.jpg&hash=1cf0395753a611f12bc5aed0ca8b016a)

Datasheet: http://www.sparkfun.com/datasheets/IC/24LC256.pdf (http://www.sparkfun.com/datasheets/IC/24LC256.pdf)
Sparkfun: http://www.sparkfun.com/commerce/product_info.php?products_id=525 (http://www.sparkfun.com/commerce/product_info.php?products_id=525)

Pois bem as EEPROMs são mesmo nossas amigas e então as i2c são tão fáceis de implementar que ao fim de algum tempo nem nos lembramos que as temos na breadboard. Estas ocupam apenas os pinos 4 e 5 analógicos do Arduino, ocupando um endereço no BUS, ou seja, podemos continuar com todos os outros dispositivos i2c que lá tinhamos ligados anteriormente.

A eeprom que vou usar neste tutorial é uma 24lc256 da Microchip. Esta eeprom tem 32K endereços a 8 bits  fazendo dela uma eeprom com 256 Kbits memória. OH yeah!
Eu gosto de comparar esta capacidade de armazenamento com quanto precisaria para guardar um bitmap a fullscreen para o meu LCD da Nokia com o controlador OM6206. Ora bem um bitmap ocupa 864 bytes, se tenho 32k bytes, quer dizer 0x7FFF bytes disponíveis na eeprom isto dá...  37,9 imagens! :D "Ya é bué" memória.
A Atmel, assim como outras marcas, também têm estas eeproms. Na Atmel é 24C256, mas as da Microchip são bem melhores! As da Microchip aguentam os dados por mais de 200 anos, na Atmel é só 40; As da Microchip dão para mais de um milhão de ciclos escrita, as da Atmel só dão para 100 mil. A Microchip dá 3 pinos para endereço, a Atmel só dá dois. Bom e continua...

As ligações são estas:

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fi240.photobucket.com%2Falbums%2Fff159%2Fsuper-mascarada%2FUntitled.jpg&hash=9ac0bbb98ff3670e1e0639c513c5dec9)

Os pinos A0 a A2 servem para indicar o endereço da eeprom no bus i2c, se estiverem todos ligados a GND o endereço no Arduino é 0x50. Assim, conseguimos ter até 8 eeproms no mesmo bus fazendo 2Mbit de memória!
O pino WP é o pino que indica se a eeprom está protegida contra escita, se ligarem este pino a vcc não podem escrever na eeprom e se o ligarem a GND já podem, é como o botão nos cartões de memória.

Depois de ligarem isto tudo vamos lá testar tudo! Para o teste ligem o WP a GND.

Código: [Seleccione]
#include <Wire.h>         // Para a EEPROM 24LC256, assim chamamos as bibliotecas i2c
#define eeprom 0x50    // endereço da eeprom já shiftado

void setup(void){
  Wire.begin();           // Iniciar ligações i2c
  Serial.begin(9600); // Assim podemos ver qualquer coisa na consola serial

  unsigned int address = 0;  //endereçamento a 2 bytes
  Serial.println("A escrever o melhor numero de sempre nos 10 primeiros bytes!");
  for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');   // Va pub a mim! Encher os 10 primeiros bytes com o número 3
  Serial.println("Vamos ler se esta tudo ok, deves ver 33, 33, 33, 33... Vá 10x 33");

  for(address = 0; address<10; address++) {
     Serial.print(readEEPROM(eeprom, address), HEX);
     Serial.print(", ");
  }
}

void loop(){
}

//-------Rotinas para EEPROMS i2c por Daniel Gonçalves a.k.a. Tr3s------
// Podem usar estas rotinas à vontade para projectos particulares.
// Para fins comerciais entrar em contacto com we_real_cool@hotmail.com
// Partilhem com apenas com o meu concentimento.
// Se virem este código noutro sitio sem ser [url=http://www.lusorobotica.com]www.lusorobotica.com[/url] avisem de imediato para we_real_cool@hotmail.com!

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(data);
  Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

// Por Daniel Gonçalves a.k.a. (t.c.p.) Tr3s, para [url=http://www.lusorobotica.com]www.lusorobotica.com[/url]

Bom e acho que é tudo... Alguma coisa é só dizer.

Vejam também o post onde ensino a brincar com a eeprom duma maneira mais gira!
http://lusorobotica.com/index.php/topic,460.msg2733.html (http://lusorobotica.com/index.php/topic,460.msg2733.html) (use Arduino to program eeprom)

NOTA: Não se esqueçam das resistências de pullup do bus I2C, para mais informação sobre o protocolo I2C visitem o link:
http://lusorobotica.com/index.php/topic,33.0.html (http://lusorobotica.com/index.php/topic,33.0.html)

Exemplo de uma imagem lida de uma eeprom por um arduino e escrita num lcd nokia:

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg172.imageshack.us%2Fimg172%2F1231%2Fsnc00101qx7.jpg&hash=d118c8e3e4c57faa1d44b25e6562ea51)
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 14:47
Muito interessante, adicionado como artigo ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: Fifas em 26 de Janeiro de 2009, 15:37
oh yeah!!! :D

muito obrigado tr3s!!!! por acaso tenho aqui uma eprom da microchip...so nao sei qual é :P nunca a usei muito por isso nao sei bem o potencial disto...

vou por um exemplo de uma coisita que tou a fazer...imagina que o arduino recebe um determinado dado por serie e eu quero que ele escreva esse dado num lcd (por exemplo do 3310) mas em forma de grafico.....se programar a eprom  para os dados do grafico fico com mais espaço livre no arduino, certo?


ps: acho que foi desta que queimei o meu arduino :P
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 26 de Janeiro de 2009, 16:08
oh yeah!!! :D

muito obrigado tr3s!!!! por acaso tenho aqui uma eprom da microchip...so nao sei qual é :P nunca a usei muito por isso nao sei bem o potencial disto...

vou por um exemplo de uma coisita que tou a fazer...imagina que o arduino recebe um determinado dado por serie e eu quero que ele escreva esse dado num lcd (por exemplo do 3310) mas em forma de grafico.....se programar a eprom  para os dados do grafico fico com mais espaço livre no arduino, certo?


ps: acho que foi desta que queimei o meu arduino :P

Queimaste porquê? :S

Sim ficas, eu estuo a supor que tens um determinado sensor e estás a registar dados de x em x tempo. Sim se os guardares para a eeprom em vez de os guardares numa zona reservada para isso no Arduino (Atmega168), ficas sem dúvida com mais espaço no Arduino. Imagina que queres guardar 5000 medições, imagina de temperatura, supondo que não passas dos 255 ºC :P, cada medição ocupa um byte, ou seja, no Arduino tinhas de reservar 5000 bytes. Isso é demais para ele, fica logo marado (embora teoricamente pudesse guardar isso). 5000 bytes na eeprom não são nada e facilmente guardas lá 32000 medições. Sem preocupações. Como dou o exemplo de medições posso dar o exemplo de pontos (GPS), caracteres, imagens duma webcam, etc. ...
Portanto, sim, pouparias imensa memória e preocupações, já que, uma vez lá guardados só se escreveres por cima é que os perdes!
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 16:27
Bastante interessante :)
 Só não percebi muito bem esta parte "Os pinos A0 a A2 servem para indicar o endereço da eeprom no bus i2c, se estiverem todos ligados a GND o endereço no Arduino é 0x50. Assim, conseguimos ter até 8 eeproms no mesmo bus fazendo 2Mbit de memória!" A verdade é que ainda não estive a ver muito bem a comunicação I2C, se calhar é por isso.
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 26 de Janeiro de 2009, 16:55
Bastante interessante :)
 Só não percebi muito bem esta parte "Os pinos A0 a A2 servem para indicar o endereço da eeprom no bus i2c, se estiverem todos ligados a GND o endereço no Arduino é 0x50. Assim, conseguimos ter até 8 eeproms no mesmo bus fazendo 2Mbit de memória!" A verdade é que ainda não estive a ver muito bem a comunicação I2C, se calhar é por isso.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fzone.ni.com%2Fcms%2Fimages%2Fdevzone%2Ftut%2FDeviceAddressing.GIF&hash=75672a52e940766d74c53fca28408de9)

Vamos então analisar a imagem de cima:

Primeiro ignora o primeiro bit (Start Bit) e o último (Acknowledge Bit) uma vez que são bits da comunicação e não fazem parte do endereçamento que queremos estudar. Ficamos com:

| 1 | 0 | 1 | 0 | A2 | A1 | A0 | R/~W |

Supondo que temos os pinos A2, A1 e A0 ligados a GND ficamos com:

| 1 | 0 | 1 | 0 | 0 | 0 | 0 | R/~W |
Isto em hexadecimal é  0xA0 ou 0xA1 consoanto o valor de R/~W

Como a biblioteca serial do Arduino "empurra" tudo para a esquerda quando faz comunicação i2c, temos de garantir que quando vem tudo para a esquerda ficamos com os valores correctos, então "empurramos" tudo para a direita antes! Perdemos R/~W (que no fundo não nos interessa porque o pino actua de qualquer maneira)

->| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 |
                           A2  A1  A0
e assim temos 0x50 em hexadecimal.

Bom este exemplo é com os pinos a 0, isto é ligados a GND. Como tens 3 pinos, tens 3 bits de combinações, ou seja ligando estes 3 pinos a VCC ou GND consegues fazer 8 endereços diferentes, são eles:
                           A2  A1  A0
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | = 0x50
| 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | = 0x51
| 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | = 0x52
| 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | = 0x53
| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | = 0x54
| 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | = 0x55
| 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | = 0x56
| 0 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | = 0x57


Agora, imagina que tens 3 eeproms na breadboard e queres so com 2 fios controlá-las todas. Dando diferentes valores nestes pinos consegues fazer que que as 3 tenham diferentes endereços. Assim consegues aceder independentemente a cada uma!

Aconcelho-te, de qualquer maneira, a ler mais sobre o protocolo i2c :D


Espero que tenhas percebido ;D
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 17:00
Percebi perfeitamente, a explicação foi bastante boa :) Obrigado :) :)
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 17:01
Muito bem explicado.

Tens aqui um artigo meu sobre I2C (http://lusorobotica.com/index.php/topic,33.0.html) que te pode ajudar a perceber melhor o protocolo, contudo consulta o manual da Philips ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 20:37
Só para concluir então, quando se utilizam sensores ou outros componentes que comuniquem utilizando I2C convem que tenham 3 bits para indicar o endereço, certo?
Título: Re:Arduino + EEPROM i2c
Enviado por: Fifas em 26 de Janeiro de 2009, 20:39
o tr3s vai dar professor ;D

boa explicaçao ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 20:46
Nem todos os sensores têm, alguns vêm só com um endereço, mas podemos jogar com os outros que são de endereços configuráveis para evitar que os endereços fiquem sobrepostos.

Nunca tentei meter dois sensores de mesmo endereço no mesmo bus para ver qual o resultado, mas certamente informação incorrecta no bus para não dizer que até pode danificar algum. (acho que não danifica mas quando tiver dinheiro para gastar em sensores que se possam danificar faço um tutorial e posto :P)
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 21:10
Adicionado datasheet e página do produto na sparkfun ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 21:22
Essa eeprom só tem 256k se não estiveres mais nada a utilizar o I2C do arduino, correcto?
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 21:27
Não interessa se tens mais coisas a utiliar i2c no arduino, sim ela tem essa capacidade interna que podes utiliza-la com qualquer microcontrolador. Essa é a quantidade de bytes que ela pode armazenar no seu interior, o arduino pode ter muitas ou poucas coisas ligadas que não vai interferir com a estrutura física da eeprom, logo não altera o seu tamanho.
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 21:31
Então não percebo isto "Esta eeprom tem 32K endereços a 8 bits  fazendo dela uma eeprom com 256 Kbits memória."  ???

Eu pensei que fosse, em cada endereço da eeprom, aqueles a0 a1 a2, tivesse 32k
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 26 de Janeiro de 2009, 21:37
Basicamente deixam-te configurar o endereço de i2c para poderes mete-la no mesmo bus que outros dispositivos sem que fique no mesmo endereço de outros dispositivos. Se não desse para configurar o bus, não podias meter varias eeproms no mesmo bus, ou outros chips que tenham o mesmo endereço de i2c. Assim como podes configurar, já podes escolher que endereço queres para a eeprom permitindo que esta fique no bus sem ficar com o mesmo endereço que já esteja a ser utilizado por outro.

Num bus i2c, cada chip tem que ter o seu endereço único que o permite falar e ouvir sem colidir dados.
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 26 de Janeiro de 2009, 21:45
Então não percebo isto "Esta eeprom tem 32K endereços a 8 bits  fazendo dela uma eeprom com 256 Kbits memória."  ???

Eu pensei que fosse, em cada endereço da eeprom, aqueles a0 a1 a2, tivesse 32k

Não confundas o endereçamento da eeprom no BUS i2c com o endereçamento à memória interna da eeprom, são coisas distintas.

Imagina que o BUS i2c é como uma rede de computadores. Para distinguires os vários computadores na rede e para comunicares para eles usas o endereço IP (isto simplificando muitoooo as redes de computadores :P), no BUS i2c é a mesma coisa. Neste, o endereço ip de cada dispositivo é o tal valor gerado pelo Control Code (interno às eeproms) + Chip Select Bits (Os pinos A2, A1 e A0). Com estes geras oito i2c IPs (endereços de dispositivos i2c).

Agora o endereçamento à memória é feito durante a comunição i2c, já depois de estabeleçida a ligação (no Arduino é Wire.begin(); para levantar o auscultador e Wire.beginTransmission(enderecoEEprom); para marcar! :P). Depois da ligação estabelecida entre o Arduino e a EEPROM, é enviado o endereço da memória à qual queres aceder e este não tem nada a haver com os pinos, isto é, com o Slave Address!
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 26 de Janeiro de 2009, 21:49
Eu já nem sei como agradecer. As tuas explicações são fantásticas :)
Título: Re:Arduino + EEPROM i2c
Enviado por: DanBar em 27 de Janeiro de 2009, 08:38
Muito bom  8)

Já agora utilizas o vb através da porta série não é. Quais os comandos que utilizas para gravar e para ler na epron.

É possivel utilizar uma aplicação que grave e reutilize a informação na EEPROM. Certo.

É possivel gravar variáveis na EEPROM para o arduino utilizar mais tarde. Como é que faço isso.

Exemplo, Estou a desenvolver um controlador da sofagem para o meu carro, e vou utilizar um comando IR universal para comandar os servos. Quero gravar todos os comandos na EEPROM.
Título: Re:Arduino + EEPROM i2c
Enviado por: microbyte em 27 de Janeiro de 2009, 09:21
Primeiro abres ligação:
SerialPort1.Open()

SerialPort1.Write()
SerialPort1.Read() ou ReadLine()
Título: Re:Arduino + EEPROM i2c
Enviado por: DanBar em 28 de Janeiro de 2009, 10:26
Boas.

Encontrei isto na net. Utilizam o lib wire para comunicar com o i2c

Está correcto ?

Código: [Seleccione]
#include <Wire.h> // include wire library

void setup()
{
  Wire.begin(0x50); // join i2c bus (address optional for master)
  Teste();
}

void loop()
{
     

}


void Teste(){       
  Wire.beginTransmission(4); // transmit to device #4
  Wire.send("lusorobotica");       // send text
  Wire.endTransmission();    // stop transmitting
  delay(500);
  }
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 22 de Fevereiro de 2009, 11:51
Tr3s, olha o que eu encontrei... este post é para ti!

Citar
I found code and tutorial for using I2C EEPROMs on the Arduino which was perfect since it would only take up 2 pins (pin 4 and 5) and I could put up to 8 EEPROMs on a single bus. The problem was that the tutorial was in Portuguese, (and I found another one in Spanish) so I ended up just fumbling through it myself. For the rest of you, here's the English guide.
Fonte:
http://www.ghettohax.com/2009/02/i2c-eeprom-for-arduino.html (http://www.ghettohax.com/2009/02/i2c-eeprom-for-arduino.html)


Ainda de outro site:

Citar
Check out this Arduino Tutorial (in Portuguese) and accompanying Windows App, by Daniel Gonçalves.
Fonte:
http://mindkits.com/_product_41557/i2c_eeprom_-_256kbit (http://mindkits.com/_product_41557/i2c_eeprom_-_256kbit)

O LusoRobótica a começar a ensinar o mundo ;)

Parabéns tr3s...
Título: Re:Arduino + EEPROM i2c
Enviado por: ricardo-reis em 22 de Fevereiro de 2009, 14:59
uma salva de palmas..  :-* :-* mt bom.. ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 22 de Fevereiro de 2009, 15:35
 :) É bom saber que o nosso fórum começa a ser reconhecido e como é claro, também é bom saber que gostam do nosso trabalho!
Obrigado a todos! :D
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 22 de Fevereiro de 2009, 15:57
Muito bem tr3s  :D
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 21 de Março de 2009, 14:52
Continuando os meus estudos nas comunicações I2C e SPI, ao analisar novamente o código mas agora com mais atenção e seguindo a datasheet também, surgiram as seguintes duvidas:

1)
Citar
Serial.println("Vamos ler se esta tudo ok, deves ver 33, 33, 33, 33... Vá 10x 33");

Porque é que aqui é 33, 33, ... e não 3, 3, 3,... ?
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 22 de Abril de 2009, 20:47
Tive a testar as minhas memorias de 512 :D :D

Queria chamar atenção para o facto de ao gravar muitos dados seguidos, quando digo muito é mesmo muitos, tipo uma imagem ou assim, poder ocorrer o facto de falhar alguns bytes por isso aconselho a quem queira gravar muitos dados de seguida e não se importe de esperar cerca de 3/4 segundos (porque sem o delay que vou aconselhar a colocar aquilo é instantâneo).
A minha solução é simplesmente colocar um delay entre as gravações no seguinte código:

Código original:
Código: [Seleccione]
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  digitalWrite(ledEstado, HIGH);
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  digitalWrite(ledEstado, LOW);
  return rdata;
}

Com os delay:
Código: [Seleccione]
byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  digitalWrite(ledEstado, HIGH);
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  digitalWrite(ledEstado, LOW);
  delay(3);
  return rdata;
}

O vídeo vai aparecer com alguns erros devido a isto que referi, não me apeteceu estar a passar novamente a passar as imagens para a memoria :P

http://www.youtube.com/watch?v=zezuNA0H1oc
Título: Re:Arduino + EEPROM i2c
Enviado por: Njay em 22 de Abril de 2009, 21:53
(...)
É possivel utilizar uma aplicação que grave e reutilize a informação na EEPROM. Certo.

É possivel gravar variáveis na EEPROM para o arduino utilizar mais tarde. Como é que faço isso.

Exemplo, Estou a desenvolver um controlador da sofagem para o meu carro, e vou utilizar um comando IR universal para comandar os servos. Quero gravar todos os comandos na EEPROM.

Se 512 bytes (1K no ATmega328) te servem, podes usar a EEPROM que faz parte do AVR do Arduino.
Tenta o seguinte:

No topo fazes:

#include <avr/eeprom.h>

Escolhes cuidadosamente em que endereços da EEPROM vais guardar cada dado, tendo em conta os tamanhos, e atribuis endereços. Evita os 1ºs 2 ou 3 bytes (endereços 0 a 2).

E depois tens esta função para escrever um bloco de bytes:

eeprom_write_block (&<variável-na-RAM>, (void*)<endereço-da-variável-na-EEPROM>, size);

E esta outra para ler um bloco de bytes:

eeprom_read_block (&<variável-na-RAM>, (void*)<endereço-da-variável-na-EEPROM>, size);

Código: [Seleccione]
#include <avr/eeprom.h>

#define EEPROM_SERVOPOS_ADDR  3

typedef struct {
    int  servo1;
    int  servo2;
} TServos;

TServos servoPos;
...
// guardar as posições em EEPROM...
eeprom_write_block (&servoPos, (void*)EEPROM_SERVOPOS_ADDR, sizeof(servoPos));
...
// recuperar as posições da EEPROM...
eeprom_read_block (&servoPos, (void*)EEPROM_SERVOPOS_ADDR, sizeof(servoPos));

Título: Re:Arduino + EEPROM i2c
Enviado por: rjrv em 23 de Abril de 2009, 01:08
Acho que está na altura de pensar num tutorial... de português!!!!! Parabéns cada vez mais internacionais!
Título: Re:Arduino + EEPROM i2c
Enviado por: ricardo-reis em 23 de Abril de 2009, 02:14
Acho que está na altura de pensar num tutorial... de português!!!!! Parabéns cada vez mais internacionais!

hás-de fazer um desenho, que, no (des)contexto não percebi essa..
Título: Re:Arduino + EEPROM i2c
Enviado por: antonio_jose em 07 de Junho de 2009, 03:24
Muito interessante

Está muito bem explicado

 ;D
Título: Re:Arduino + EEPROM i2c
Enviado por: Reonarudo em 07 de Junho de 2009, 10:46
Atenção que a memória interna EEPROM do arduino tem um nº de escritas e leituras limitado eu se for programar um rede neuronal num arduino esgotava as escritas e leituras todas
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 07 de Junho de 2009, 11:55
Todas as memórias tem um tempo de vida, se utilizares muito intensivamente uma pen por exemplo, também se danificam sectores. No fundo são as propriedades químicas dos componentes que se vão perdendo por estarem constantemente a comutar de estado.
Título: Re:Arduino + EEPROM i2c
Enviado por: Reonarudo em 07 de Junho de 2009, 12:21
Pois é, o que quis dizer é que a memória do arduino tem um tempo de vida muito reduzido
Título: Re:Arduino + EEPROM i2c
Enviado por: Njay em 07 de Junho de 2009, 13:04
Apenas as memórias persistentes do mega168 têm uma vida limitada. Desde que utilizado sempre dentro das especificações, o fabricante (ATMEL) garante que:

1) A memória de programa (FLASH) pode ser escrita/apagada pelo menos 10000 vezes

2) A memória de dados (EEPROM) pode ser escrita/apagada pelo menos 100000 vezes

Estes valores são aquilo a que se chama "endurance". Pode parecer muito mas se escrevessem dados na EEPROM 1 vez por segundo ela só durava 1 dia e umas horas. Portanto estas memórias são para ser usadas só esporádicamente, como por exemplo para guardar configurações do utilizador de umas utilizações para as outras.

A ATMEL também dá outra especificação que é a "data retention", e que indica durante quanto tempo a memória "segura" os dados guardados . No caso dos AVRs modernos esses valores são

1) Pelo menos 20 anos se a temperatura ambiente for mantida a 85ºC
2) Pelo menos 100 anos se a temperatura ambiente for mantida a 25ºC

A temperatura reduz o tempo de retenção; quanto mais quente, menos tempo aguenta (os dados derretem, lol). Entre os 2 valores acima há uma "curva". Não sei se é linear, mas se fosse, isto queria dizer por exemplo que a (25+85)/2= 55ºC a retenção seria de pelo menos (100+20)/2= 60 anos.

Estes valores são dados para todas as memórias "EEPROM". A EEPROM i2c de que fala a mensagem original também terá estes valores na sua datasheet.
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 08 de Junho de 2009, 11:16
...

Estes valores são dados para todas as memórias "EEPROM". A EEPROM i2c de que fala a mensagem original também terá estes valores na sua datasheet.

Exactamente Njay!  :D (Como sempre, tudo super bem explicado!)
No post inicial , há uma altura em que comparo as EEPROM da Microchip com as da Atmel e chego a referir a característica dos ciclos de escrita/leitura serem finitos e da capacidade de retenção de dados com o tempo! :)
Título: Re:Arduino + EEPROM i2c
Enviado por: Reonarudo em 08 de Junho de 2009, 13:29
Em vez de usar eeproms não compensaria usar sdcards? ??? ::)
Título: Re:Arduino + EEPROM i2c
Enviado por: metRo_ em 08 de Junho de 2009, 13:52
Em vez de usar eeproms não compensaria usar sdcards? ??? ::)

Os sdcards nunca testei mas duvido que seja mais simples que estas memorias, estas memorias são a coisa mais simples que há :)
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 08 de Junho de 2009, 13:55
Eu ando agora a preparar um tutorial para SD card com Arduino, mas estou a ter uns problemas com o controlo de FAT.

Depois quando estiver tudo a funcionar posto ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 08 de Junho de 2009, 13:58
O código que é preciso para poderes escrever e ler em SD cards é muito grande pelo que já li... Enche a memoria quase toda! Tigpt, tu que tas a fazer experiências, quanto te ocupa?
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 08 de Junho de 2009, 14:07
Anda por volta dos 7Kb
Título: Re:Arduino + EEPROM i2c
Enviado por: Reonarudo em 08 de Junho de 2009, 14:42
Então nem é assim tanto e se for feita uma boa API é tão simples de usar como outra memoria qualquer tem a desvantagem de ocupar mais memória mas tem a vantagem de ser facilmente substituível.
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 08 de Junho de 2009, 14:52
Então nem é assim tanto e se for feita uma boa API é tão simples de usar como outra memoria qualquer tem a desvantagem de ocupar mais memória mas tem a vantagem de ser facilmente substituível.

Eu acho que é difícil justificares o uso de SD em situações em que podes utilizar uma EEPROM. Repara que num ATmega128 com o bootloader do Arduino estás a ocupar METADE da memória de código disponível apenas para ler e escrever num SD... Já para não falar que se usa um sistema de ficheiros antigo e ultrapassado/obsoleto chamado FAT... Mais, pelo que tenho lido não funciona muito bem nem imlpementa todas as funcionalidades do sistema de ficheiros (criação de ficheiros, directorias etc).
O que entendes por "ser facilmente substituivel"? ???
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 08 de Junho de 2009, 14:59
É bom para se quisermos fazer logs bastante grandes de dados, como por exemplo, gravar temperatura e pressão atmosférica a cada meio segundo.

Contudo não é fácil utilizar, e do que consigo nem dá para criar pastas ou ficheiros, o ficheiro tem que já existir para podermos adicionar-lhe dados.

Quando conseguir meter a funcionar posto.
Título: Re:Arduino + EEPROM i2c
Enviado por: tr3s em 08 de Junho de 2009, 15:24
Claro, mas o que eu disse foi "acho que é difícil justificares o uso de SD em situações em que podes utilizar uma EEPROM", repara "situações em que podes utilizar uma EEPROM"! :P
Título: Re:Arduino + EEPROM i2c
Enviado por: TigPT em 08 de Junho de 2009, 16:19
Claro tr3s... estava só a acrescentar ;)
Título: Re:Arduino + EEPROM i2c
Enviado por: Reonarudo em 08 de Junho de 2009, 17:51
Hehe
Eu por acaso só tenho um 168 e o resto é 328 por isso não achei que fosse assim tanta ocupação.
Tiago se quiseres ajuda com isso é só dizer...
Título: Re:Arduino + EEPROM i2c
Enviado por: Njay em 08 de Junho de 2009, 23:47
Até que não é muito dificil fazer uma interface básica com um SD card, especialmente quando já há código feito ;). Em tempo fiz um projecto com um AVR e um SD card, também é um logger, e era suposto logar periodicamente o estado de 8 entradas digitais. Não vou repetir aqui a ladaínha porque já o escrevi noutro fórum:

http://www.electronicapt.com/forum/empty-t2201.0.html (http://www.electronicapt.com/forum/empty-t2201.0.html)

O programa todo (interface SD card + o resto) ocupa menos de 2KB.
Título: Re: Arduino + EEPROM i2c
Enviado por: naf18 em 27 de Março de 2010, 21:12
ola alguem me pode dar uma ajuda no i2c?
Estou a tentar ligar o arduino a um sensor da freescale e esta a dar um erro: o arduino fica bloqueado. o codigo que tenho é o seguinte:

Citar
#include <Wire.h>

#define Slave_adress (0x4D)

void setup()
{
   Serial.begin(9600);      // open the serial port at 9600 bps:   
   Wire.begin();   // start Wire library as I2C-Bus Master
}
void loop()
{
 Serial.println("vai escrever");
 Write_I2C(0x03, 0x11);
 Serial.println("escreveu");
}

void Write_I2C(int command, int data) {
  //  Send config register address
  Wire.beginTransmission((int)(Slave_adress));
  Wire.send((int)(command));
  Wire.send((int)(data));
  Wire.endTransmission();
}

Já fiz vários testes e verifiquei que ele blaqueia quando vai executar a linha wire.endTransmisson();

Se alguém souber como ajudar agradecia.
Título: Re: Arduino + EEPROM i2c
Enviado por: dio123 em 07 de Julho de 2012, 13:45
Bom dia,

Qual é a diferença entre usar #include <Wire.h>  ou a #include <eeprom.h>             

Para exprimentar umas eeproms que tinha aqui em casa usei o eeprom.h e funcionou bem, mas depois de uma pesquisa na net vejo que há muita pessoas a usar wire.h
Título: Re: Arduino + EEPROM i2c
Enviado por: senso em 07 de Julho de 2012, 14:12
Wire.h é a biblioteca para usar I2C, eeprom.h deve ter meia duzia de funções para ler as eeproms sem andar com o baixo nivel do i2c, mas a eeprom tem de incluir a biblioteca i2c se não, não funciona.
Título: Re: Arduino + EEPROM i2c
Enviado por: dio123 em 07 de Julho de 2012, 16:20
usei o exemplo daqui deste tópico.   E aparece assim:  33, FF, FF, FF, FF, FF, FF, FF, FF, FF,
Exprimentei um novo e acontece a mesma coisa.
Exprimentei um velho que tenho aqui e aparece 33, 22, 42, 65, 21, 77, 47,48,49, 11,

E depois exprimentei todos mas com resistencias 4k7 ligadas ao pinos 4 e 5 e 5v e acontece a mesma coisa.
Verifiquei os fios novamente, e está tudo correcto.
Título: Re: Arduino + EEPROM i2c
Enviado por: senso em 07 de Julho de 2012, 16:55
Então, mas o velho o mais certo é teres já metido para lá dados e o novo ainda está por meter lá dados dentro, uma eeprom "formatada" está cheia de FF's.
Título: Re: Arduino + EEPROM i2c
Enviado por: dio123 em 07 de Julho de 2012, 17:37
Mas o codigo que está no primeiro 1ºpost não devia preecher as 10 primeiras posições com 33. e depois devia aparece
33,33,33,33,33,33,33,33,33,33

é que a mim só preeche a 1º posição. Coloquei resistencias 4k7 e 10k nos pinos 4e 5  nao resolveu o problema
Título: Re: Arduino + EEPROM i2c
Enviado por: iyahdub em 31 de Julho de 2012, 16:02
Parece mais que gravaste os 3 em ASCII so uma vez, e o resto nao deve ter recebido nada ja que esta ao maximo dos 256 ...Vazia ?!

usei o exemplo daqui deste tópico.   E aparece assim:  33, FF, FF, FF, FF, FF, FF, FF, FF, FF,
Exprimentei um novo e acontece a mesma coisa.
Exprimentei um velho que tenho aqui e aparece 33, 22, 42, 65, 21, 77, 47,48,49, 11,

E depois exprimentei todos mas com resistencias 4k7 ligadas ao pinos 4 e 5 e 5v e acontece a mesma coisa.
Verifiquei os fios novamente, e está tudo correcto.
Título: Re: Arduino + EEPROM i2c
Enviado por: dio123 em 31 de Julho de 2012, 20:21
eu usei o codigo que está no 1º post do tutorial.
Título: Re: Arduino + EEPROM i2c
Enviado por: rglove em 23 de Agosto de 2012, 15:55
Boas, estive a ler este tutorial com mais atenção e acho que percebi quase tudo, mas há uma coisa que não percebi no código. Pela datasheet vê-se que se tem de enviar o MSB seguido do LSB, o que não percebo é o significado das 2 "expressões" que convertem o endereço para MSB e LSB. Alguém me explica sff?

Código: [Seleccione]
void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(data);
  Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

Cumprimentos
Título: Re: Arduino + EEPROM i2c
Enviado por: senso em 23 de Agosto de 2012, 22:18
O valor do endereço está guardado numa variavel de 16 bits, vamos supor arbitráriamente que o seu valor é de 0xABCD em hexadecimal.
A primeira operação:
Código: [Seleccione]
Wire.send((int)(eeaddress >> 8));   // MSBFica: 0xABCD >> 8 que dá 0xAB, pois é um shift right á direita de 8 bits, e como tal, os bits que representavam 0xCD foram mandados para fora da variavel e fica só 0xAB.

A segunda operação:
Código: [Seleccione]
Wire.send((int)(eeaddress & 0xFF)); // LSBFica 0xABCD & 0x00FF, o valor 0xFF é extendido a 16 bits, e como os 8 bits mais significantes não está definidos, são definidos como 0's, o & é o operador lógico AND, e qualquer coisa AND 0 dá sempre zero(é tipo como multiplicar por zero), e assim o valor fica 0xCD.

Assim o valor de 16 bits foi partido em dois valores de 8 bits, para serem enviados por i2c/twi que é um interface que opera ao nivel do byte, ou seja só podes enviar 1 byte em cada transação de dados efectuada.
Título: Re: Arduino + EEPROM i2c
Enviado por: rglove em 23 de Agosto de 2012, 23:02
Percebi perfeitamente, obrigado  ;)
Título: Re: Arduino + EEPROM i2c
Enviado por: miragempro em 09 de Setembro de 2012, 00:28
BOM NOITE AMIGO DE PORTUGAL, SOU O EDUARDO DO BRASIL/SP

BEM... sou estudante iniciante em programação,  e estou estudando arduino, mas eu tenho um projeto em que preciso fazer um porteiro eletronico.

Pensei em faze-lo em wi-fi, mas como automatizar a frequencia para que não preciso busca-la sempre?  sabes alguma coisa a respeito?

Obrigado

Hi,

E que tal falar sobre EEPROMs?

Ora bem, quase todos devem saber o que são e o jeitão que dão quando começamos a ficar sem espaço no nosso microcontrolador e temos a necessidade migrar dados, ou então quando queremos fazer muitos registos e os míseros bytes de memória que o nosso micro tem não são suficientes.

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fwww.sparkfun.com%2Fcommerce%2Fimages%2Fproducts%2FEEPROM.jpg&hash=1cf0395753a611f12bc5aed0ca8b016a)

Datasheet: http://www.sparkfun.com/datasheets/IC/24LC256.pdf (http://www.sparkfun.com/datasheets/IC/24LC256.pdf)
Sparkfun: http://www.sparkfun.com/commerce/product_info.php?products_id=525 (http://www.sparkfun.com/commerce/product_info.php?products_id=525)

Pois bem as EEPROMs são mesmo nossas amigas e então as i2c são tão fáceis de implementar que ao fim de algum tempo nem nos lembramos que as temos na breadboard. Estas ocupam apenas os pinos 4 e 5 analógicos do Arduino, ocupando um endereço no BUS, ou seja, podemos continuar com todos os outros dispositivos i2c que lá tinhamos ligados anteriormente.

A eeprom que vou usar neste tutorial é uma 24lc256 da Microchip. Esta eeprom tem 32K endereços a 8 bits  fazendo dela uma eeprom com 256 Kbits memória. OH yeah!
Eu gosto de comparar esta capacidade de armazenamento com quanto precisaria para guardar um bitmap a fullscreen para o meu LCD da Nokia com o controlador OM6206. Ora bem um bitmap ocupa 864 bytes, se tenho 32k bytes, quer dizer 0x7FFF bytes disponíveis na eeprom isto dá...  37,9 imagens! :D "Ya é bué" memória.
A Atmel, assim como outras marcas, também têm estas eeproms. Na Atmel é 24C256, mas as da Microchip são bem melhores! As da Microchip aguentam os dados por mais de 200 anos, na Atmel é só 40; As da Microchip dão para mais de um milhão de ciclos escrita, as da Atmel só dão para 100 mil. A Microchip dá 3 pinos para endereço, a Atmel só dá dois. Bom e continua...

As ligações são estas:

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fi240.photobucket.com%2Falbums%2Fff159%2Fsuper-mascarada%2FUntitled.jpg&hash=9ac0bbb98ff3670e1e0639c513c5dec9)

Os pinos A0 a A2 servem para indicar o endereço da eeprom no bus i2c, se estiverem todos ligados a GND o endereço no Arduino é 0x50. Assim, conseguimos ter até 8 eeproms no mesmo bus fazendo 2Mbit de memória!
O pino WP é o pino que indica se a eeprom está protegida contra escita, se ligarem este pino a vcc não podem escrever na eeprom e se o ligarem a GND já podem, é como o botão nos cartões de memória.

Depois de ligarem isto tudo vamos lá testar tudo! Para o teste ligem o WP a GND.

Código: [Seleccione]
#include <Wire.h>         // Para a EEPROM 24LC256, assim chamamos as bibliotecas i2c
#define eeprom 0x50    // endereço da eeprom já shiftado

void setup(void){
  Wire.begin();           // Iniciar ligações i2c
  Serial.begin(9600); // Assim podemos ver qualquer coisa na consola serial

  unsigned int address = 0;  //endereçamento a 2 bytes
  Serial.println("A escrever o melhor numero de sempre nos 10 primeiros bytes!");
  for(address = 0; address<10; address++) writeEEPROM(eeprom, address, '3');   // Va pub a mim! Encher os 10 primeiros bytes com o número 3
  Serial.println("Vamos ler se esta tudo ok, deves ver 33, 33, 33, 33... Vá 10x 33");

  for(address = 0; address<10; address++) {
     Serial.print(readEEPROM(eeprom, address), HEX);
     Serial.print(", ");
  }
}

void loop(){
}

//-------Rotinas para EEPROMS i2c por Daniel Gonçalves a.k.a. Tr3s------
// Podem usar estas rotinas à vontade para projectos particulares.
// Para fins comerciais entrar em contacto com we_real_cool@hotmail.com
// Partilhem com apenas com o meu concentimento.
// Se virem este código noutro sitio sem ser [url=http://www.lusorobotica.com]www.lusorobotica.com[/url] avisem de imediato para we_real_cool@hotmail.com!

void writeEEPROM(int deviceaddress, unsigned int eeaddress, byte data ) {
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.send(data);
  Wire.endTransmission();
}

byte readEEPROM(int deviceaddress, unsigned int eeaddress ) {
  byte rdata = 0xFF;
  Wire.beginTransmission(deviceaddress);
  Wire.send((int)(eeaddress >> 8));   // MSB
  Wire.send((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
  Wire.requestFrom(deviceaddress,1);
  if (Wire.available()) rdata = Wire.receive();
  return rdata;
}

// Por Daniel Gonçalves a.k.a. (t.c.p.) Tr3s, para [url=http://www.lusorobotica.com]www.lusorobotica.com[/url]

Bom e acho que é tudo... Alguma coisa é só dizer.

Vejam também o post onde ensino a brincar com a eeprom duma maneira mais gira!
http://lusorobotica.com/index.php/topic,460.msg2733.html (http://lusorobotica.com/index.php/topic,460.msg2733.html) (use Arduino to program eeprom)

NOTA: Não se esqueçam das resistências de pullup do bus I2C, para mais informação sobre o protocolo I2C visitem o link:
http://lusorobotica.com/index.php/topic,33.0.html (http://lusorobotica.com/index.php/topic,33.0.html)

Exemplo de uma imagem lida de uma eeprom por um arduino e escrita num lcd nokia:

(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fimg172.imageshack.us%2Fimg172%2F1231%2Fsnc00101qx7.jpg&hash=d118c8e3e4c57faa1d44b25e6562ea51)
Título: Re: Arduino + EEPROM i2c
Enviado por: rglove em 17 de Setembro de 2012, 11:39
eu usei o codigo que está no 1º post do tutorial.

Não quero desenterrar tópicos, mas acho importante dizer que com um delay entre as escritas na eeprom consegue-se escrever tudo.

Hoje chegaram as minhas eeproms e também só recebia o primeiro byte escrito. Após meter um delay de 10ms entre as escritas já consegui escrever bem na eeprom (não experimentei delays mais pequenos).

O tutorial está muito bom :)
Título: Re: Arduino + EEPROM i2c
Enviado por: rglove em 18 de Setembro de 2012, 01:58
Não sei se deveria ter criado um novo tópico para isto, mas assim fica aqui para outras pessoas que possam vir a ter a mesma dúvida que eu...

No caso de usar uma 24LC1025, que tem 128k de endereços, como é que o endereço é enviado para a EEPROM? Como 16 bits = valor máximo de 65535 e a EEPROM tem 128k endereços se quiser escrever num endereço superior a 65535 como faço? Já estive a ver na datasheet, mas o que está lá é que o endereço ocupa 16 bits...

Se alguém me puder ajudar...  :)

Cumprimentos

EDIT: Por preguiça não li a parte do Control Byte com atenção... Parece que essa EEPROM está dividida em 2 blocos de 512k bits e o pino A2 é o pino de seleção dos blocos. Amanhã já experimento  :P
Título: Re: Arduino + EEPROM i2c
Enviado por: tr3s em 18 de Setembro de 2012, 09:34
É isso, é no control message, mas é o block select bit, que vem a seguir aos control bits ;)

O Pino A2 é nao configuravel e deverá estar ligado a VCC salvo erro. Os pinos A0 e A1 definem o endereço do dispositivo no BUS i2c (é necessário indicar este endereço na mensagem de controlo!)
Título: Re: Arduino + EEPROM i2c
Enviado por: rglove em 18 de Setembro de 2012, 14:25
Já era tarde e não pensei quando estava a escrever   :P

É isso mesmo, à noite experimento  :)
Título: Re: Arduino + EEPROM i2c
Enviado por: jpombas em 03 de Fevereiro de 2014, 18:19
Boas,
estou a trabalhar com o Arduino YUN, mas devido à sua capacidade fui obrigado a programar em python, de modo a processar os dados no processador "Linino". Mesmo assim estou com dificuldade em programar implementado o shield TFT, uma vez que a biblioteca é muito pesada.
Gostava de saber se existe alguma forma de "aumentar" a memoria dedicada a programas ou até como libertar espaço das biblioteca eliminando recursos desnecessários.
Aguardo resposta breve,
Cumprimentos
Título: Re: Arduino + EEPROM i2c
Enviado por: Nunito em 03 de Fevereiro de 2014, 20:29
Boa noite.
Por favor dirija-se à secção das apresentações.
Sempre fica mais bem visto fazendo a sua apresentação.

Obrigado