Loading...
Pages: [1]   Go Down
Author Topic: LCD ST7565  (Read 395 times)
0 Members and 1 Guest are viewing this topic.
L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi, i have the graphic Display ST7565 (Adafruit); i have a little problem with it, because i need to print "Int" and "Long" characters on this screen but i can't find a Function  inside the Library that can do this.   smiley-mad


The Library that i use is: ST7565 LCD library

this library have a function called "drawstring" that receives input character type "Char*" and if i send "Int" ther's an error (obviously), and so i tried to transform the "Int" in a "Char" using the function "itoa()" and  it  work but don't write on the screen the "Int" characters.

Please can someone help me? smiley-roll-sweat
Logged

Roberto

Germany
Offline Offline
God Member
*****
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

The related code and the current output would help a lot.

You could also use http://code.google.com/p/u8glib/ which is derived from the Aruduino print class (you can use everything described here: http://arduino.cc/en/Serial/Print).

Oliver
Logged

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is the code of the Library:

Code:
.....

static void updateBoundingBox(uint8_t xmin, uint8_t ymin, uint8_t xmax, uint8_t ymax) {
#ifdef enablePartialUpdate
  if (xmin < xUpdateMin) xUpdateMin = xmin;
  if (xmax > xUpdateMax) xUpdateMax = xmax;
  if (ymin < yUpdateMin) yUpdateMin = ymin;
  if (ymax > yUpdateMax) yUpdateMax = ymax;
#endif
}

void ST7565::drawbitmap(uint8_t x, uint8_t y,
const uint8_t *bitmap, uint8_t w, uint8_t h,
uint8_t color) {
  for (uint8_t j=0; j<h; j++) {
    for (uint8_t i=0; i<w; i++ ) {
      if (pgm_read_byte(bitmap + i + (j/8)*w) & _BV(j%8)) {
my_setpixel(x+i, y+j, color);
      }
    }
  }

  updateBoundingBox(x, y, x+w, y+h);
}

void ST7565::drawstring(uint8_t x, uint8_t line, char *c) {
  while (c[0] != 0) {
    drawchar(x, line, c[0]);
    c++;
    x += 6; // 6 pixels wide
    if (x + 6 >= LCDWIDTH) {
      x = 0;    // ran out of this line
      line++;
    }
    if (line >= (LCDHEIGHT/8))
      return;        // ran out of space :(
  }
}


void ST7565::drawstring_P(uint8_t x, uint8_t line, const char *str) {
  while (1) {
    char c = pgm_read_byte(str++);
    if (! c)
      return;
    drawchar(x, line, c);
    x += 6; // 6 pixels wide
    if (x + 6 >= LCDWIDTH) {
      x = 0;    // ran out of this line
      line++;
    }
    if (line >= (LCDHEIGHT/8))
      return;        // ran out of space :(
  }
}

void  ST7565::drawchar(uint8_t x, uint8_t line, char c) {
  for (uint8_t i =0; i<5; i++ ) {
    st7565_buffer[x + (line*128) ] = pgm_read_byte(font+(c*5)+i);
    x++;
  }

  updateBoundingBox(x, line*8, x+5, line*8 + 8);
}


// bresenham's algorithm - thx wikpedia
void ST7565::drawline(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1,
      uint8_t color) {
  uint8_t steep = abs(y1 - y0) > abs(x1 - x0);
  if (steep) {
    swap(x0, y0);
    swap(x1, y1);
  }

  if (x0 > x1) {
    swap(x0, x1);
    swap(y0, y1);
  }

  // much faster to put the test here, since we've already sorted the points
  updateBoundingBox(x0, y0, x1, y1);

  uint8_t dx, dy;
  dx = x1 - x0;
  dy = abs(y1 - y0);

  int8_t err = dx / 2;
  int8_t ystep;

  if (y0 < y1) {
    ystep = 1;
  } else {
    ystep = -1;}

  for (; x0<=x1; x0++) {
    if (steep) {
      my_setpixel(y0, x0, color);
    } else {
      my_setpixel(x0, y0, color);
    }
    err -= dy;
    if (err < 0) {
      y0 += ystep;
      err += dx;
    }
  }
}

// filled rectangle
void ST7565::fillrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
      uint8_t color) {

  // stupidest version - just pixels - but fast with internal buffer!
  for (uint8_t i=x; i<x+w; i++) {
    for (uint8_t j=y; j<y+h; j++) {
      my_setpixel(i, j, color);
    }
  }

  updateBoundingBox(x, y, x+w, y+h);
}

// draw a rectangle
void ST7565::drawrect(uint8_t x, uint8_t y, uint8_t w, uint8_t h,
      uint8_t color) {
  // stupidest version - just pixels - but fast with internal buffer!
  for (uint8_t i=x; i<x+w; i++) {
    my_setpixel(i, y, color);
    my_setpixel(i, y+h-1, color);
  }
  for (uint8_t i=y; i<y+h; i++) {
    my_setpixel(x, i, color);
    my_setpixel(x+w-1, i, color);
  }

  updateBoundingBox(x, y, x+w, y+h);
}

// draw a circle outline
void ST7565::drawcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color) {
  updateBoundingBox(x0-r, y0-r, x0+r, y0+r);

  int8_t f = 1 - r;
  int8_t ddF_x = 1;
  int8_t ddF_y = -2 * r;
  int8_t x = 0;
  int8_t y = r;

  my_setpixel(x0, y0+r, color);
  my_setpixel(x0, y0-r, color);
  my_setpixel(x0+r, y0, color);
  my_setpixel(x0-r, y0, color);

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
 
    my_setpixel(x0 + x, y0 + y, color);
    my_setpixel(x0 - x, y0 + y, color);
    my_setpixel(x0 + x, y0 - y, color);
    my_setpixel(x0 - x, y0 - y, color);
   
    my_setpixel(x0 + y, y0 + x, color);
    my_setpixel(x0 - y, y0 + x, color);
    my_setpixel(x0 + y, y0 - x, color);
    my_setpixel(x0 - y, y0 - x, color);
   
  }



}

void ST7565::fillcircle(uint8_t x0, uint8_t y0, uint8_t r,
uint8_t color) {
  updateBoundingBox(x0-r, y0-r, x0+r, y0+r);

  int8_t f = 1 - r;
  int8_t ddF_x = 1;
  int8_t ddF_y = -2 * r;
  int8_t x = 0;
  int8_t y = r;

  for (uint8_t i=y0-r; i<=y0+r; i++) {
    my_setpixel(x0, i, color);
  }

  while (x<y) {
    if (f >= 0) {
      y--;
      ddF_y += 2;
      f += ddF_y;
    }
    x++;
    ddF_x += 2;
    f += ddF_x;
 
    for (uint8_t i=y0-y; i<=y0+y; i++) {
      my_setpixel(x0+x, i, color);
      my_setpixel(x0-x, i, color);
    }
    for (uint8_t i=y0-x; i<=y0+x; i++) {
      my_setpixel(x0+y, i, color);
      my_setpixel(x0-y, i, color);
    }   
  }
}

void ST7565::my_setpixel(uint8_t x, uint8_t y, uint8_t color) {
  if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
    return;

  // x is which column
  if (color)
    st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8)); 
  else
    st7565_buffer[x+ (y/8)*128] &= ~_BV(7-(y%8));
}

// the most basic function, set a single pixel
void ST7565::setpixel(uint8_t x, uint8_t y, uint8_t color) {
  if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
    return;

  // x is which column
  if (color)
    st7565_buffer[x+ (y/8)*128] |= _BV(7-(y%8)); 
  else
    st7565_buffer[x+ (y/8)*128] &= ~_BV(7-(y%8));

  updateBoundingBox(x,y,x,y);
}


// the most basic function, get a single pixel
uint8_t ST7565::getpixel(uint8_t x, uint8_t y) {
  if ((x >= LCDWIDTH) || (y >= LCDHEIGHT))
    return 0;

  return (st7565_buffer[x+ (y/8)*128] >> (7-(y%8))) & 0x1; 
}

void ST7565::begin(uint8_t contrast) {
  st7565_init();
  st7565_command(CMD_DISPLAY_ON);
  st7565_command(CMD_SET_ALLPTS_NORMAL);
  st7565_set_brightness(contrast);
}

void ST7565::st7565_init(void) {
  // set pin directions
  pinMode(sid, OUTPUT);
  pinMode(sclk, OUTPUT);
  pinMode(a0, OUTPUT);
  pinMode(rst, OUTPUT);
  pinMode(cs, OUTPUT);

  // toggle RST low to reset; CS low so it'll listen to us
  if (cs > 0)
    digitalWrite(cs, LOW);

  digitalWrite(rst, LOW);
  _delay_ms(500);
  digitalWrite(rst, HIGH);

  // LCD bias select
  st7565_command(CMD_SET_BIAS_7);
  // ADC select
  st7565_command(CMD_SET_ADC_NORMAL);
  // SHL select
  st7565_command(CMD_SET_COM_NORMAL);
  // Initial display line
  st7565_command(CMD_SET_DISP_START_LINE);

  // turn on voltage converter (VC=1, VR=0, VF=0)
  st7565_command(CMD_SET_POWER_CONTROL | 0x4);
  // wait for 50% rising
  _delay_ms(50);

  // turn on voltage regulator (VC=1, VR=1, VF=0)
  st7565_command(CMD_SET_POWER_CONTROL | 0x6);
  // wait >=50ms
  _delay_ms(50);

  // turn on voltage follower (VC=1, VR=1, VF=1)
  st7565_command(CMD_SET_POWER_CONTROL | 0x7);
  // wait
  _delay_ms(10);

  // set lcd operating voltage (regulator resistor, ref voltage resistor)
  st7565_command(CMD_SET_RESISTOR_RATIO | 0x6);

  // initial display line
  // set page address
  // set column address
  // write display data

  // set up a bounding box for screen updates

  updateBoundingBox(0, 0, LCDWIDTH-1, LCDHEIGHT-1);
}

.....
Logged

Roberto

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have also tried the library u8glib but this error occurs when compiling:
Code:
sketch_apr10d.cpp: In function 'void draw()':
sketch_apr10d:104: error: 'u8g' was not declared in this scope
sketch_apr10d.cpp: In function 'void loop()':
sketch_apr10d:117: error: 'u8g' was not declared in this scope
Logged

Roberto

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok i have resolved all the problem, now work perfectly   smiley-razz
Logged

Roberto

Germany
Offline Offline
God Member
*****
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, great i just was about to post another comment.

Oliver
Logged

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Work perfectly the LCD but it don't write the "Int" Character another time.
For example:
Code:
void loop(void) {
  // picture loop
  u8g.firstPage(); 
  do {
    u8g.setFont(u8g_font_gdr25);
    u8g.print(5);
    draw();
  } while( u8g.nextPage() );
 
  // rebuild the picture after some delay
  delay(500);
}

i have used the "print()" function and the compiling don't give any error but on the screen nothing appear.
why??
Logged

Roberto

Germany
Offline Offline
God Member
*****
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You must apply a suitable print position. To draw a string at position 10,10 use

Code:
u8g.setPrintPos(10, 10)

Use this just before the print command.

Oliver
Logged

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfect!  smiley  smiley smiley smiley

now i have another question:
if i want to draw a bitmap that i have on my PC, how i can load on my LCD?
Logged

Roberto

Germany
Offline Offline
God Member
*****
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to convert the bitmap to black/white XBM format (for example with gimp). This XBM format actually is an array of bytes which can be used as argument for drawXBM or drawXBMP.

Oliver
Logged

L'aquila
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Come on Eagles
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i have created the ".xbm" file, but how can i add this at the function "drawXBM"?  smiley-roll-sweat

i tried in this way, but don't work:
Code:
...
u8g.drawXBM(65,12,61,50,"car.xbm");
...
Logged

Roberto

Germany
Offline Offline
God Member
*****
Karma: 69
Posts: 840
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

Have a look at the XBM example code in the IDE: You need to copy the content of the file (car.xbm) into your .ino file. See also http://code.google.com/p/u8glib/wiki/userreference#drawXBM.

Oliver
Logged

Pages: [1]   Go Up
Print
 
Jump to: