LusoRobótica - Robótica em Português

Robótica => Tutoriais => Tópico iniciado por: BaNoBi em 25 de Agosto de 2010, 18:44

Título: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: BaNoBi em 25 de Agosto de 2010, 18:44
Boas Pessoal,

Não sei se existe por aqui alguém com experiência nisto, mas aqui vai.

Gravei um bitmap numa eeprom externa e agora queria fazer o load do bitmap e colocá-la no GLCD. Mas a única função que o GLCD têm é GLCD.DrawBitmap(const uint8_t * bitmap, uint8_t x, uint8_t y, uint8_t color);

Não estou a conseguir dar volta a esta questão.

Obrigado desde já,
Vasco Cruz
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: metRo_ em 25 de Agosto de 2010, 19:03
Boas Pessoal,

Não sei se existe por aqui alguém com experiência nisto, mas aqui vai.

Gravei um bitmap numa eeprom externa e agora queria fazer o load do bitmap e colocá-la no GLCD. Mas a única função que o GLCD têm é GLCD.DrawBitmap(const uint8_t * bitmap, uint8_t x, uint8_t y, uint8_t color);

Não estou a conseguir dar volta a esta questão.

Obrigado desde já,
Vasco Cruz
Não percebi o teu problema. Teras que ler os dados da epprom, criar o bitmap e depois chamar essa função. Algo do género GLCD.DrawBitmap(bitmap,0,0,cor);
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: BaNoBi em 25 de Agosto de 2010, 19:54
Já consegui resolver o problema com a leitura e escrita da EEPROM.

Neste momento o meu problema é mostrar no GLCD, aparecem só uns pontos, a imagem não aparece bem :(

Estou a usar este código:
Código: [Seleccione]
#include <Wire.h>
#include <ks0108.h>
#include "Image.h"

#define I2C_CONFIG 0x50
#define ADDRESS_FOR_CONFIG 0

uint8_t *gv_image;

void setup() {
  Serial.begin(115200);

  Wire.begin();
  delay(500);
 
  //writeImage(Image);
 
  readImage();
 
  GLCD.Init(NON_INVERTED);
  GLCD.ClearScreen();
 
  GLCD.DrawBitmap(gv_image, 1, 1, BLACK);
 
}

void loop() {
}

void readImage() {
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)(ADDRESS_FOR_CONFIG >> 8));   // MSB
  Wire.send((int)(ADDRESS_FOR_CONFIG & 0xFF)); // LSB
  Wire.endTransmission();

  Wire.requestFrom(I2C_CONFIG, 2); 
  int lv_width = Wire.receive();
  int lv_height = Wire.receive();
  Wire.endTransmission();
 
  Serial.print(lv_width);
  Serial.print("x");
  Serial.println(lv_height);
   
  int lv_dimension = 2 + (lv_width * (lv_height / 8));
  Serial.println(lv_dimension);
 
  gv_image = (uint8_t*)malloc(lv_dimension + sizeof(uint8_t));
 
  gv_image[0] = lv_width;
  gv_image[1] = lv_height;
 
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)((ADDRESS_FOR_CONFIG + 2) >> 8));   // MSB
  Wire.send((int)((ADDRESS_FOR_CONFIG + 2) & 0xFF)); // LSB
  Wire.endTransmission();

  Wire.requestFrom(I2C_CONFIG, lv_dimension);
 
  for(int i = 2; i < lv_dimension; i ++) {
    uint8_t displayData = Wire.receive();
    gv_image[i] = displayData;
    delay(3);
  }
 
  for(int i = 0; i < lv_dimension; i ++) {
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(gv_image[i], DEC);
    delay(3);
  }
}

void writeImage(const uint8_t * bitmap) {
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)(ADDRESS_FOR_CONFIG >> 8));   // MSB
  Wire.send((int)(ADDRESS_FOR_CONFIG & 0xFF)); // LSB
     
  Serial.println(Image[0], DEC);
  Serial.println(Image[1], DEC);
 
  int lv_dimension = 2 + (Image[0] * (Image[1] / 8));
  Serial.println(lv_dimension);
 
  for( int i = 0; i < lv_dimension; i ++) {
    uint8_t displayData = ReadPgmData(bitmap++);
    Wire.send(displayData);
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(displayData, DEC);
    delay(3);
  }
  Wire.endTransmission();
}
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: BaNoBi em 25 de Agosto de 2010, 22:16
Já consegui avançar um pouco mais.

Tive de criar uma nova função na livraria do GLCD, porque a DrawBitmap usa o método ReadPgmData para ler o valor, visto a imagem ser colocada na SRAM.

Criei a função DrawBitmap2  :) que lê o valor da variável bitmap, assim bitmap[ i ].

Agora não estou é a conseguir ler bem as 4 últimas posições da EEPROM.

A imagem tem 16 por 16 pixeis, por isso o array tem 34 posições.
Largura: 16
Altura: 16
Dimensão do array: (Largura * (Altura / 8)) = 16 * (16 / 8) = 16 * 2 = 32
                                32 + 2 (Para guardar a largura e a altura) = 34

Valores de output da escrita da imagem na EEPROM:
0 - 16; 1 - 16; 2 - 255; 3 - 1; 4 - 253; 5 - 5; 6 - 245; 7 - 21; 8 - 213; 9 - 85;
10 - 85; 11 - 213;12 - 21; 13 - 245; 14 - 5; 15 - 253; 16 - 1; 17 - 255; 18 - 255; 19 - 128;
20 - 191; 21 - 160; 22 - 175; 23 - 168; 24 - 171; 25 - 170; 26 - 170; 27 - 171; 28 - 168; 29 - 175;
30 - 160; 31 - 191; 32 - 128; 33 - 255;

Valores de output da leitura da imagem da EEPROM:
0 - 16; 1 - 16; 2 - 255; 3 - 1; 4 - 253; 5 - 5; 6 - 245; 7 - 21; 8 - 213; 9 - 85;
10 - 85; 11 - 213; 12 - 21; 13 - 245; 14 - 5; 15 - 253; 16 - 1; 17 - 255; 18 - 255; 19 - 128;
20 - 191; 21 - 160; 22 - 175; 23 - 168; 24 - 171; 25 - 170; 26 - 170; 27 - 171; 28 - 168; 29 - 175;
30 - 255; 31 - 255; 32 - 0; 33 - 0;
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: ricardo-reis em 25 de Agosto de 2010, 22:29
o que é isso do glcd 128*64 ? tens foto do lcd? algum link?

ou sou eu que não percebi a tua ideia ou a matemática anda a falhar-me, mas.. tu consegues guardar uma imagem de 16*16, mais 2 variáveis em 34 posições d'array?
suponho eu que cada bit da imagem seja uma posição de array, o que te leva a ter um array de 256 posições.. mais as duas posições que tu queres de altura e largura..

não percebo os teus cálculos de todo..
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: BaNoBi em 25 de Agosto de 2010, 22:37
GLCD = Graphics LCD

O meu é idêntico a este (128x64 pixeis):
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Fwww.pjrc.com%2Fteensy%2Ftd_libs_GLCD_1.jpg&hash=9e4a0c87c30c53451849a2ea8baebb167ab33b53)

Este é o código da imagem:
Código: [Seleccione]
static uint8_t Image[] PROGMEM = {
  16, // width
  16, // height

  /* page 0 (lines 0-7) */
  0xff,0x1,0xfd,0x5,0xf5,0x15,0xd5,0x55,0x55,0xd5,0x15,0xf5,0x5,0xfd,0x1,0xff,
 
  /* page 1 (lines 8-15) */
  0xff,0x80,0xbf,0xa0,0xaf,0xa8,0xab,0xaa,0xaa,0xab,0xa8,0xaf,0xa0,0xbf,0x80,0xff
 
};

Sim, eu preciso de um array com 34 posições para guardar toda a imagem, como podes ver no código acima.
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: ricardo-reis em 25 de Agosto de 2010, 22:40
ok.. com 'pacotes' de 8 bits.. compreendi..
Título: Re: Arduino + EEPROM i2c + GLCD 128x64
Enviado por: BaNoBi em 25 de Agosto de 2010, 23:09
Muito obrigado pela ajuda, mas já consegui resolver  :D :)

Conclusão (Fonte: http://www.arduino.cc/playground/Code/I2CEEPROM (http://www.arduino.cc/playground/Code/I2CEEPROM)):
Processo de escrita: data can be maximum of about 30 bytes, because the Wire library has a buffer of 32 bytes.
Processo de leitura: maybe let's not read more than 30 or 32 bytes at a time!

Código final:
Código: [Seleccione]
#include <Wire.h>
#include <ks0108.h>
#include "Image.h"

#define I2C_CONFIG 0x50
#define ADDRESS_FOR_CONFIG 50

uint8_t *gv_image;

void setup() {
  Serial.begin(115200);

  Wire.begin();
  delay(500);
 
  //writeImage(Image);
 
  readImage();
 
  GLCD.Init(NON_INVERTED);
  GLCD.ClearScreen();
 
  GLCD.DrawBitmap2(gv_image, 1, 1, BLACK);
  free(gv_image);
 
}

void loop() {
}

void readImage() {
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)(ADDRESS_FOR_CONFIG >> 8));   // MSB
  Wire.send((int)(ADDRESS_FOR_CONFIG & 0xFF)); // LSB
  Wire.endTransmission();

  Wire.requestFrom(I2C_CONFIG, 2); 
  int lv_width = Wire.receive();
  int lv_height = Wire.receive();
  Wire.endTransmission();
 
  Serial.print(lv_width);
  Serial.print("x");
  Serial.println(lv_height);
   
  int lv_dimension = 2 + (lv_width * (lv_height / 8));
  Serial.println(lv_dimension);
 
  gv_image = (uint8_t*)malloc(lv_dimension * sizeof(uint8_t));
 
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)(ADDRESS_FOR_CONFIG >> 8));   // MSB
  Wire.send((int)(ADDRESS_FOR_CONFIG & 0xFF)); // LSB
  Wire.endTransmission();

  Wire.requestFrom(I2C_CONFIG, lv_dimension);
 
  for(int i = 0; i < lv_dimension; i ++) {
    if(i > 0  && (i % 30) == 0) {
      Serial.print("End transmission for clear buffer, new address ");
      Serial.print((ADDRESS_FOR_CONFIG + i));
      Serial.println(".");
      Wire.endTransmission();
      Wire.beginTransmission(I2C_CONFIG);
      Wire.send((int)((ADDRESS_FOR_CONFIG + i) >> 8));   // MSB
      Wire.send((int)((ADDRESS_FOR_CONFIG + i) & 0xFF)); // LSB 
      Wire.endTransmission();
   
      Wire.requestFrom(I2C_CONFIG, (lv_dimension - i));   
    }
    uint8_t displayData = Wire.receive();
   
    gv_image[i] = displayData;
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(gv_image[i], DEC);
  }
  Wire.endTransmission();
}

void writeImage(const uint8_t * bitmap) {
  Wire.beginTransmission(I2C_CONFIG);
  Wire.send((int)(ADDRESS_FOR_CONFIG >> 8));   // MSB
  Wire.send((int)(ADDRESS_FOR_CONFIG & 0xFF)); // LSB
     
  Serial.println(Image[0], DEC);
  Serial.println(Image[1], DEC);
 
  int lv_dimension = 2 + (Image[0] * (Image[1] / 8));
  Serial.println(lv_dimension);
 
  for( int i = 0; i < lv_dimension; i ++) {
    if(i > 0  && (i % 30) == 0) {
      Serial.print("End transmission for clear buffer, new address ");
      Serial.print((ADDRESS_FOR_CONFIG + i));
      Serial.println(".");
      Wire.endTransmission();
      Wire.beginTransmission(I2C_CONFIG);
      Wire.send((int)((ADDRESS_FOR_CONFIG + i) >> 8));   // MSB
      Wire.send((int)((ADDRESS_FOR_CONFIG + i) & 0xFF)); // LSB     
    }
    uint8_t displayData = ReadPgmData(bitmap++);
    Wire.send(displayData);
    delay(100);
    Serial.print(i);
    Serial.print(" - ");
    Serial.println(displayData, DEC);
  }
  Wire.endTransmission();
}