Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Graphic LCD 96x64 w/ SED1565 Controller

Status
Not open for further replies.
i think i got it now lol im so dumb lol

Its cool i edited like this : (cuz i forget everything trust me lol )
Code:
/**********************************************************
           draw a line between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setline(char top0, char left0, char top1, char left1) {

	int dy = left1 - left0;
	int dx = top1 - top0;
	int stepx, stepy;

	if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
	if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
	dy <<= 1; // dy is now 2*dy
	dx <<= 1; // dx is now 2*dx
	lcd_setpixel(top0, left0);
	
	if (dx > dy) {
		int fraction = dy - (dx >> 1); // same as 2*dy - dx
		while (top0 != top1) {
			if (fraction >= 0) {
				left0 += stepy;
				fraction -= dx; // same as fraction -= 2*dx
			}
			top0 += stepx;
			fraction += dy; // same as fraction -= 2*dy
			lcd_setpixel(top0, left0);
		}
	} else {
		int fraction = dx - (dy >> 1);
		while (left0 != left1) {
			if (fraction >= 0) {
				top0 += stepx;
				fraction -= dy;
			}
			left0 += stepy;
			fraction += dx;
			lcd_setpixel(top0, left0);
		}
	}
}
/**********************************************************
           draw a circle between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setcircle(char top, char left, char radius) {

	int f = 1 - radius;
	int ddF_x = 0;
	int ddF_y = -2 * radius;
	int x = 0;
	int y = radius;

	lcd_setpixel(top, left + radius);
	lcd_setpixel(top, left - radius);
	lcd_setpixel(top + radius, left);
	lcd_setpixel(top - radius, left);
	while(x < y) {
		if(f >= 0) {
			y--;
			ddF_y += 2;
			f += ddF_y;
		}
		x++;
		ddF_x += 2;
		f += ddF_x + 1;
		lcd_setpixel(top + x, left + y);
		lcd_setpixel(top - x, left + y);
		lcd_setpixel(top + x, left - y);
		lcd_setpixel(top - x, left - y);
		lcd_setpixel(top + y, left + x);
		lcd_setpixel(top - y, left + x);
		lcd_setpixel(top + y, left - x);
		lcd_setpixel(top - y, left - x);
	}
}
 
Last edited:
i think i got it now lol im so dumb lol

Its cool i edited like this lol : Point0(x,y) and Point1(x.y)

it would be quite nice to develop a structure type like that. not terribly important but nice. in my last iteration, I added another parameter to decide on if I want to set or clear the line / circle / rect / ..., rather than using a set() and then a clr().
 
Last edited:
heh i like the normal names because i might be smart sometimes but im dumb the rest :D and tend to forget a lot of things. This just helps... hence why i changed again to

Top0, Left0
Top1, Left1
 
the upper left is (0,0), the lower right is (64, 132).

however, the first and the last 18 columns in the Nokia screen don't show. so you will have to remember that.

I did it that way so the program can be easily ported to other true SED1565 displays.

why not just +18 like:

Code:
void lcd_setline(char top0, char left0, char top1, char left1) {

	int dy;
	int dx;
	int stepx, stepy;

   	left0 = left0 + 18;
	left1 = left1 + 18;

	dy = left1 - left0;
	dx = top1 - top0;

	if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
	if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
	dy <<= 1; // dy is now 2*dy
	dx <<= 1; // dx is now 2*dx
	lcd_setpixel(top0, left0);
	
	if (dx > dy) {
		int fraction = dy - (dx >> 1); // same as 2*dy - dx
		while (top0 != top1) {
			if (fraction >= 0) {
				left0 += stepy;
				fraction -= dx; // same as fraction -= 2*dx
			}
			top0 += stepx;
			fraction += dy; // same as fraction -= 2*dy
			lcd_setpixel(top0, left0);
		}
	} else {
		int fraction = dx - (dy >> 1);
		while (left0 != left1) {
			if (fraction >= 0) {
				top0 += stepx;
				fraction -= dy;
			}
			left0 += stepy;
			fraction += dx;
			lcd_setpixel(top0, left0);
		}
	}
}
 
Now you can:

Code:
		lcd_setline(0,95,64,95);
		lcd_setline(64,0,64,95);
		lcd_setline(0,0,64,0);
		lcd_setline(0,0,0,95);

to get:
 

Attachments

  • square.jpg
    square.jpg
    129.7 KB · Views: 261
I am going to edit some of the code with the +18 because its a few functions with that issue.

More coding would give you:
menu-jpg.30588


Code:
Code:
		lcd_setline(0,95,64,95);
		lcd_setline(64,0,64,95);
		lcd_setline(0,0,64,0);
		lcd_setline(0,0,0,95);

		lcd_setline(52,0,52,95);

		lcd_setline(52,40,64,40);
		lcd_setline(52,54,64,54);

		lcd_str(55,7,"Menu1",NORMAL);
		lcd_str(55,60,"Menu2",NORMAL);
		lcd_str(55,46,"k",NORMAL);

		lcd_setcircle(58,47,5);

using this altered code:
Code:
/**********************************************************
           draw a line between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setline(char top0, char left0, char top1, char left1) {

	int dy;
	int dx;
	int stepx, stepy;

   	left0 += 18;
	left1 += 18;

	dy = left1 - left0;
	dx = top1 - top0;

	if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
	if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
	dy <<= 1; // dy is now 2*dy
	dx <<= 1; // dx is now 2*dx
	lcd_setpixel(top0, left0);
	
	if (dx > dy) {
		int fraction = dy - (dx >> 1); // same as 2*dy - dx
		while (top0 != top1) {
			if (fraction >= 0) {
				left0 += stepy;
				fraction -= dx; // same as fraction -= 2*dx
			}
			top0 += stepx;
			fraction += dy; // same as fraction -= 2*dy
			lcd_setpixel(top0, left0);
		}
	} else {
		int fraction = dx - (dy >> 1);
		while (left0 != left1) {
			if (fraction >= 0) {
				top0 += stepx;
				fraction -= dy;
			}
			left0 += stepy;
			fraction += dx;
			lcd_setpixel(top0, left0);
		}
	}
}
/**********************************************************
           draw a circle between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setcircle(char top, char left, char radius) {

	int f = 1 - radius;
	int ddF_x = 0;
	int ddF_y = -2 * radius;
	int x = 0;
	int y = radius;

	left += 18;

	lcd_setpixel(top, left + radius);
	lcd_setpixel(top, left - radius);
	lcd_setpixel(top + radius, left);
	lcd_setpixel(top - radius, left);
	while(x < y) {
		if(f >= 0) {
			y--;
			ddF_y += 2;
			f += ddF_y;
		}
		x++;
		ddF_x += 2;
		f += ddF_x + 1;
		lcd_setpixel(top + x, left + y);
		lcd_setpixel(top - x, left + y);
		lcd_setpixel(top + x, left - y);
		lcd_setpixel(top - x, left - y);
		lcd_setpixel(top + y, left + x);
		lcd_setpixel(top - y, left + x);
		lcd_setpixel(top + y, left - x);
		lcd_setpixel(top - y, left - x);
	}
}
/**********************************************************
           Write a string at current screen position
**********************************************************/
void lcd_str(char lcd_row, char lcd_col, const char *str, char attribute) {

	char i=0;
	lcd_col += 18;
  while (*str) {
		lcd_chr(lcd_row, lcd_col+i, *str++, attribute); 
		i+=6;
	}
	
}

I didnt touch lcd_chr just incase it gets called somewhere else in the future :D
 

Attachments

  • menu.jpg
    menu.jpg
    32.3 KB · Views: 713
Last edited:
Jason: that will work. you can also use the lcd_setrect() function to draw a box.

I didn't +18 so the same code can be ported to true sed1565-based displays.
 
oh ok i see now... lol

you can simply add :
Code:
#ifdef NOKIA7110
	left += 18;
#endif
remember to
Code:
#define NOKIA7110
Code:
/**********************************************************
           Write a string at current screen position
**********************************************************/
void lcd_str(char lcd_row, char lcd_col, const char *str, char attribute) {

	char i=0;
#ifdef NOKIA7110
	lcd_col += 18;
#endif
  while (*str) {
		lcd_chr(lcd_row, lcd_col+i, *str++, attribute); 
		i+=6;
	}
	
}

/**********************************************************
           draw a line between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setline(char top0, char left0, char top1, char left1) {

	int dy;
	int dx;
	int stepx, stepy;

#ifdef NOKIA7110
   	left0 += 18;
	left1 += 18;
#endif
	dy = left1 - left0;
	dx = top1 - top0;

	if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; }
	if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; }
	dy <<= 1; // dy is now 2*dy
	dx <<= 1; // dx is now 2*dx
	lcd_setpixel(top0, left0);
	
	if (dx > dy) {
		int fraction = dy - (dx >> 1); // same as 2*dy - dx
		while (top0 != top1) {
			if (fraction >= 0) {
				left0 += stepy;
				fraction -= dx; // same as fraction -= 2*dx
			}
			top0 += stepx;
			fraction += dy; // same as fraction -= 2*dy
			lcd_setpixel(top0, left0);
		}
	} else {
		int fraction = dx - (dy >> 1);
		while (left0 != left1) {
			if (fraction >= 0) {
				top0 += stepx;
				fraction -= dy;
			}
			left0 += stepy;
			fraction += dx;
			lcd_setpixel(top0, left0);
		}
	}
}
/**********************************************************
           draw a circle between two points
					 code shamelessly stolen from Jim Lynch's 6100 driver
					 which itself is based on Jack Bresenham's line algorithm
**********************************************************/
void lcd_setcircle(char top, char left, char radius) {

	int f = 1 - radius;
	int ddF_x = 0;
	int ddF_y = -2 * radius;
	int x = 0;
	int y = radius;
#ifdef NOKIA7110
	left += 18;
#endif
	lcd_setpixel(top, left + radius);
	lcd_setpixel(top, left - radius);
	lcd_setpixel(top + radius, left);
	lcd_setpixel(top - radius, left);
	while(x < y) {
		if(f >= 0) {
			y--;
			ddF_y += 2;
			f += ddF_y;
		}
		x++;
		ddF_x += 2;
		f += ddF_x + 1;
		lcd_setpixel(top + x, left + y);
		lcd_setpixel(top - x, left + y);
		lcd_setpixel(top + x, left - y);
		lcd_setpixel(top - x, left - y);
		lcd_setpixel(top + y, left + x);
		lcd_setpixel(top - y, left + x);
		lcd_setpixel(top + y, left - x);
		lcd_setpixel(top - y, left - x);
	}
}

This is what happens when you dont define the NOKIA7110...
nodefine-jpg.30593


and when you do:
menu-jpg.30592


EDIT

what setrect?
I didnt get that code :D
 

Attachments

  • menu.jpg
    menu.jpg
    32.3 KB · Views: 719
  • noDEfine.jpg
    noDEfine.jpg
    28.7 KB · Views: 698
Last edited:
sorry, I may have added it after I posted it.

here is the latest. I just started but haven't finished yet the bmp function, lcd_setbmp(), so as is the program doesn't compile.
 

Attachments

  • Nokia 7110.zip
    6.2 KB · Views: 233
if you leave the BMP as one big block then you can just:
Code:
void lcd_setbmp(const char *bmp, char set_clr) {
	char i, j;

	for (i=0; i<=8; i++)
		for (j=0; j<=132; j++)
			lcd_write_byte(i, j, *bmp++, NORMAL);//[i][j], NORMAL);


}
also why are you using 132? if its 96 pixels wide? or is this another thing to fit that controller
 
Last edited:
Hey i was using your new code and notice it doesnt let me write a character pass a certain point look:

Code:
		lcd_setrect(0,0,95,64,SET);
		lcd_setrect(52,0,95,64,SET);
		lcd_setrect(52,40,16,64,SET);

		lcd_str(55,42,"OK",NORMAL);
		lcd_str(55,7,"ItemA",NORMAL);
		lcd_str(55,58,"ItemA",NORMAL);
 

Attachments

  • asd.jpg
    asd.jpg
    16.1 KB · Views: 256
Ya, those are the line and circle functions I used. rectangle too:

Code:
void lcd7110_set_rect(int x0, int y0, int x1, int y1)
{
    lcd7110_set_line(x0, y0, x1, y0);
    lcd7110_set_line(x0, y1, x1, y1);
    lcd7110_set_line(x0, y0, x0, y1);
    lcd7110_set_line(x1, y0, x1, y1);
}

Writing each pixel individually just doesn't work for me. For an 8x6 character you are setting/clearing each bit individually and doing 4 writes to the LCD for each pixel. That's 192 writes to the LCD for each character. I'd like to do scrolling and that would totally kill a large write of characters to the screen.

Currently I'm tracking each page that is changed and doing a quick write of the page lines that have changed when I call a refresh. I'd like to have it track more specific page/columns that changed, but I'm not certain if that's necessary. A page line refresh is quicker than I can detect and even when writing a circle or rectangle that goes over multiple pages, I can't actually see the writing.

Here's my code. AT91SAM7S256 - Compiles under Crossworks or GCC ARM.
I was going to clean this up and add some comments, but I went out all day today. I don't know when I'll get to this again, so here it is.
**broken link removed**
 
Jason:

I think I was limiting the right edge to a certain point, it is in either lcd_write_byte() or lcd_write_chr() - they do a boundary check, on illegal char or illegal address at the begining of the function call.

I think the lcd_write_byte() can be significantly improved while preserving portability. it is literally drawing the char bit by bit, thus the slow speed.
 
"I'd like to do scrolling and that would totally kill a large write of characters to the screen."

on scrolling: if you dynamically move the comm line, it will cause the entire screen to scroll - it is mentioned in the datasheet and it worked when I tried it.
 
on scrolling: if you dynamically move the comm line, it will cause the entire screen to scroll - it is mentioned in the datasheet and it worked when I tried it.

Cool, thanks. I don't know if I'll have time to look at all this again for a few days at least.
 
I just ordered two of these from dipmicro. I just need something to read out the values of a few variables, hopefully with all the code you guys have posted that shouldn't be too hard. Thanks!
 
The smooth scroll works, but it's a little disappointing. It looks like the refresh rate of the LCD itself is to blame, but it kinda blinks as it moves from one frame to another. Sending a whole page of data to the screen is actually very fast, and there is no detectable delay from the top of the screen to the bottom.

The slight blink makes the scroll a little jarring to look at.
 
Back to this old thread, but I found out something pretty bizarre just now. I took off my LCD PCB off the breadboard in order measure how much current it pulls, because my ground and power lines are hidden under the PCB, only to find that I've never attached the power wire, only the ground. All this time, it looks like my LCD has been powered by the data lines alone. Not certain how this works, but it does. So, I'm just shrugging my shoulders over this one.

I ported over a simplified text only library to the MSP430 and I have the whole processor and LCD running on a CR2032 battery. It's pretty cool, because with no sleep mode or any power saving and full clock, it all takes 2.3mA, which should last 95 hours on a CR2032 coin cell battery.
 
awesome! so my remote is very do-able with 2-4AA batteries :D

I plan on buying a XLP:
**broken link removed**

Since it can save alot of energy and have it in DEEP sleep most of the time and 1 button to wakeup. this way it will last long without a recharge.

EDIT:

Most likely ill get a PIC18F46J50 to test it out and see how much current the entire project takes in sleep/deep sleep/normal operations
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top