Go Down

Topic: Arduino Mega + LCD TFT01: bitmap, memoria, etc (Read 998 times) previous topic - next topic

Osias Neto

Galera,
Estou usando um Arduino mega para controlar um LCD grafico 320x240 (inclusive recomendo, é barato e bem legal de mexer).
link: http://www.elecfreaks.com/wiki/index.php?title=2.4%22_TFT_LCD:_TFT01-2.4

Encontrei uma biblioteca para controlá-lo que facilita bastante o trabalho: link: http://www.henningkarlsen.com/electronics/library.php?id=51

Aí a dúvida é o seguinte:
eu gero a array uint16 contendo uma bitmap, usando o PROGMEM, então usando a função da lib, ele desenha o bitmap na tela do LCD. Até aí tudo bem, o caso é que eu entendo que posso armazenar quantos BMPs minha flash permitir, mas não é isso o que acontece. Se eu excedo um certo limite de memória na soma dos bytes da bmp, ele imprime lixo na LCD, inclusive com pedaços de BMPs de softwares antigos, o que pode estar acontecendo?

Aqui um trecho de uma das bitmaps:
Code: [Select]
// Generated by   : ImageConverter 565 Online
// Generated from : graph.png
// Time generated : Fri, 18 Oct 13 18:06:19 +0200  (Server timezone: CET)
// Image Size     : 56x56 pixels
// Memory usage   : 6272 bytes

#include <avr/pgmspace.h>

prog_uint16_t graph[3136] PROGMEM={
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0020 (32) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0030 (48) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xDF79, 0xDF58, 0xDF58, 0xDF58,   // 0x0040 (64) pixels
0xDF58, 0xDF58, 0xDF58, 0xDF58, 0xDF58, 0xDF58, 0xDF58, 0xDF58, 0xD758, 0xE77A, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0050 (80) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0060 (96) pixels
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,   // 0x0070 (112) pixels...................
};


Aqui o código no Arduino:
Code: [Select]
#include <UTFT.h>
#include <avr/pgmspace.h>
#include "draws.h"; // que contem os bitmaps

// Declare which fonts we will be using
extern uint8_t SmallFont[];

// Uncomment the next line for Arduino 2009/Uno
//UTFT myGLCD(ITDB32S,19,18,17,16);   // Remember to change the model parameter to suit your display module!

// Uncomment the next line for Arduino Mega
UTFT myGLCD(SSD1289,38,39,40,41);   // Remember to change the model parameter to suit your display module!


void setup()
{
 myGLCD.InitLCD();
 myGLCD.setFont(SmallFont);
}

void loop()
{  
 myGLCD.fillScr(255, 255, 255);
 myGLCD.setColor(255, 255, 255);
 myGLCD.drawBitmap (64, 24, 56, 56, graph, 3);
 delay(5000);
}


E aqui o trecho da lib que excuta a impressão da bmp:
Code: [Select]
void UTFT::drawBitmap(int x, int y, int sx, int sy, bitmapdatatype data, int scale)
{
unsigned int col;
int tx, ty, tc, tsx, tsy;
byte r, g, b;

if (scale==1)
{
if (orient==PORTRAIT)
{
cbi(P_CS, B_CS);
setXY(x, y, x+sx-1, y+sy-1);
for (tc=0; tc<(sx*sy); tc++)
{
col=pgm_read_word(&data[tc]);
LCD_Write_DATA(col>>8,col & 0xff);
}
sbi(P_CS, B_CS);
}
else
{
cbi(P_CS, B_CS);
for (ty=0; ty<sy; ty++)
{
setXY(x, y+ty, x+sx-1, y+ty);
for (tx=sx-1; tx>=0; tx--)
{
col=pgm_read_word(&data[(ty*sx)+tx]);
LCD_Write_DATA(col>>8,col & 0xff);
}
}
sbi(P_CS, B_CS);
}
}
else
{
if (orient==PORTRAIT)
{
cbi(P_CS, B_CS);
for (ty=0; ty<sy; ty++)
{
setXY(x, y+(ty*scale), x+((sx*scale)-1), y+(ty*scale)+scale);
for (tsy=0; tsy<scale; tsy++)
for (tx=0; tx<sx; tx++)
{
col=pgm_read_word(&data[(ty*sx)+tx]);
for (tsx=0; tsx<scale; tsx++)
LCD_Write_DATA(col>>8,col & 0xff);
}
}
sbi(P_CS, B_CS);
}
else
{
cbi(P_CS, B_CS);
for (ty=0; ty<sy; ty++)
{
for (tsy=0; tsy<scale; tsy++)
{
setXY(x, y+(ty*scale)+tsy, x+((sx*scale)-1), y+(ty*scale)+tsy);
for (tx=sx-1; tx>=0; tx--)
{
col=pgm_read_word(&data[(ty*sx)+tx]);
for (tsx=0; tsx<scale; tsx++)
LCD_Write_DATA(col>>8,col & 0xff);
}
}
}
sbi(P_CS, B_CS);
}
}
clrXY();
}


Este exemplo funciona bem, mas se por exemplo eu duplicar a bmp graph, gerando graph2, graph3, graph4... e mandar imprimir seguidamente no loop, a imagem gerada aparece cheia de lixo.

Osias Neto

Ninguém? Não preciso de uma solução, apenas de uma explicação se possível...

HugoPT

Ola amigo
Quote
Se eu excedo um certo limite de memória na soma dos bytes da bmp, ele imprime lixo na LCD, inclusive com pedaços de BMPs de softwares antigos, o que pode estar acontecendo?

De que limite estas a falar em termos de bytes?
Como usas o mega ele tem um maximo de flash de 256 KB se for o 2560.Assim axo pouco provável que o teu problema seja mesmo o tamanho do bitmap na flash mas sim a quantidade de bytes que podes desenhar no ecra na dimensão que desejas.
Imagina o seguinte:
O teu ecra tem uma dimensão máxima de 320*240( vamos pressupor), com esta dimensão necessitas de x bytes para preencher todo o ecra.Se excederes esse limite algo ira acontecer pois nao tens mais espaço para escreveres no LCD, provavelmente ira escrever por cima , ou talvez o defeito que apresentas.
Quando usei um displau grafico (um epson S1D13700) acontecia me o que dizes.Imagina tinha um bitmap a ser apresentado corretamente.Ai alterava a posição onde devia começar a escrever e puff era so artefactos no LCD.
Conclusão se geraste o bitmap para uma dimensão de X nao podes aumentar os bitmaps para mais nem a posiçao onde os escreves.
Isto foi a minha conclusao pode estar errada ...
Ja agora o que estas a usar para gerar os bitmaps?
Debian,Mint,Ubuntu
Arduino Mega 2560
Arduino Nano
Arduino Duemilanove
MAC OS Montain Lion
Raspberry PI Model B

bubulindo

Pergunta óbvia... quanto é que tens livres de flash?

Porque é que meteste aqui o código que funciona em vez do código que não funciona? Se este funciona, não podemos fazer muito nele, ou podemos?

Isso que dizes de aparecer bitmaps antigos é interessante e indica-me que pode estar a haver algum problema com apontadores. Assim de repente não sei como é que o Arduino grava o programa, se apaga tudo e volta a escrever tudo deixando espaco livre, ou se só escreve o novo programa onde é preciso escrever.

Mas sem ver o código que não funciona, não podemos fazer muito... quando compilas o programa do Arduino, que é que aparece no final acerca do tamanho do programa?

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Osias Neto

Quote
De que limite estas a falar em termos de bytes?

É o atmega1280, 128k de flash, 8k de sram

Quote
axo pouco provável que o teu problema seja mesmo o tamanho do bitmap na flash mas sim a quantidade de bytes que podes desenhar no ecra na dimensão que desejas.

Sim, eu cheguei nesta conclusão tambem, gera erros de print na tela bastante aleatorios quando a imagem é maior que o ecra, mas não é esse o caso...

É assim: se eu armazeno (apenas por questão de exemplo) a mesma imagem três vezes (podem ser três diferentes), com nomes diferentes, e mando imprimir na tela as "três bmps", ela imprime cada uma perfeitamente. Agora, se eu crio uma quarta bmp, mesmas dimensões, mesmo tamanho, etc, e mando imprimir as 4, as 4 imprimem com erros!

Acredito estar relacionado à como é tratado o PROGMEM, ou talvez em como a lib utiliza este recurso, mas não faço ideia do que realmente possa ser.

Quote
Pergunta óbvia... quanto é que tens livres de flash?

Muita!... Brincadeiras a parte, uns 60k.

Quote
Porque é que meteste aqui o código que funciona em vez do código que não funciona? Se este funciona, não podemos fazer muito nele, ou podemos?

Pois o código que não funciona é o mesmo com mais imagens armazenadas na flash. Mesmo que eu não use todas, que no software eu só use uma bmp das armazenadas, e só uma vez, só pelo fato de eu carregar o bmp no Arduino como no exemplo, qualquer bmp que imprimir aparece com lixo.

Quote
Isso que dizes de aparecer bitmaps antigos é interessante e indica-me que pode estar a haver algum problema com apontadores.

Tem razão, provavelmente ele não zera memória toda, pois há bastante diferença de tempo de carregamento de acordo com o tamanho final do programa.

O tamanho fica em 71K, sendo que aproximadamente 39k são de bmps

bubulindo

Não sei mesmo o que poderá estar a acontecer, mas pela descrição há algo na gestão de memória que não está a funcionar.
Só o facto do programa dar erro por ter variáveis declaradas sem serem usadas indica isso.

Estou a pensar que testes podes fazer para tentar perceber o que se passa... Mas não me ocorre assim nada excepto carregares um dos exemplos com bmps e ver se a funcionalidade se mantém.

Eu não sou o teu criado. Se respondo no fórum é para ajudar todos mediante a minha disponibilidade e disposição. Responder por mensagem pessoal iria contra o propósito do fórum e por isso evito-o.
Se realmente pretendes que eu te ajude por mensagem pessoal, então podemos chegar a um acordo e contrato onde me pagas pela ajuda que eu fornecer e poderás então definir os termos de confidencialidade do meu serviço. De forma contrária toda e qualquer ajuda que eu der tem de ser visível a todos os participantes do fórum (será boa ideia, veres o significado da palavra fórum).
Nota também que eu não me responsabilizo por parvoíces escritas neste espaço pelo que se vais seguir algo dito por mim, entende que o farás por tua conta e risco.

Dito isto, mensagens pessoais só se forem pessoais, ou seja, se já interagimos de alguma forma no passado ou se me pretendes convidar para uma churrascada com cerveja (paga por ti, obviamente).

Go Up