Simple signal drawing on graphical LCD routines

During my spare time, I have been playing with graphical LCD. This time I decided to display simple signals that are stored in microcontroller memory. The idea was to read signal values from a lookup table and display waveform on Graphical LCD. To make things more interesting, I divided the LCD screen into four smaller screens to activate them separately and draw signals in them.

Graphical LCD is the same old HQM1286404 with KS0108 controller. I have used  Proteus simulator 128×64 graphical LCD(LGM12641BS1R), which is based on KS0108. How to implement and connect LCD there was a blog post (Simulate KS0108 graphical LCD with Proteus simulator

)about it. I am just going to show main program routine.

As I mentioned I have split 128×64 in to four smaller screens like this:

So I get four smaller 32×63 screens where I can put different information. To do this, you can think of many ways of implementation. I have chosen a simple solution. I have created a simple structure that holds a currently active window position and size:

//structure of window coordinates
struct window{
	uint8_t xmin;
	uint8_t ymin;
	uint8_t xmax;
	uint8_t ymax;
} win;

And I wrote a function which changes the active window.

void setWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
{
	//clear previous window frame
	ks0108DrawRect(win.xmin, win.ymin, win.xmax-win.xmin, win.ymax-win.ymin, WHITE);
	//set new window position and size
	win.xmin=x0;
	win.ymin=y0;
	win.xmax=x1;
	win.ymax=y1;
	//draw frame on active window
	ks0108DrawRect(win.xmin, win.ymin, win.xmax-win.xmin, win.ymax-win.ymin, BLACK);
}

It just assigns new coordinates to a new window. Also, it draws a rectangle around the active window. When changing the window position to the new, the old rectangle is deleted. So this makes a pretty cool effect. 

After the window setting is done, it is time to write a signal drawing function that takes values from the pointed look-up table and draws it on the LCD active window. The function is really simple; the only thing you have to take care of is correct proportions:

void drawSignal(uint8_t X0, uint8_t Y0, uint8_t A, uint8_t R,const uint8_t *FlashLoc)
{
	uint8_t tval, prx=X0, pry=Y0, x=X0, y, i;
	//read first point value
	tval=pgm_read_byte(&FlashLoc[0]);
	//calculate y position
	y=(int)((float)(tval-(win.xmax+1))/256*A)+Y0;
	//set dot in calculated position
	ks0108SetDot(x++, y, BLACK);
	//repeat until end of frame reached
	for(i=R; ((i<=(255-R))&&(x<=win.xmax)); i+=R)
		{
			tval=pgm_read_byte(&FlashLoc[i]);
			y=(int)((float)(tval-(win.xmax+1))/256*A)+Y0;
			//draw line
			ks0108DrawLine(prx, pry, x++, y, BLACK);
			//remember last point coordinates
			prx=x;
			pry=y;
		}
}

The drawing function has several parameters. X0 and Y0 are signal starting coordinates on LCD. A is amplitude, R is resolution. The resolution allows to squeeze or expand signal. And, of course, a pointer to the signal table.

Now what you have to do in the main() program stream is to set active window size and draw signal.

//set active window area
setWindow(0,0,63,31);
//draw signal
drawSignal(win.xmin, win.ymin+(uint8_t)((win.ymax-win.ymin)/2), 10, 					(uint8_t)(256/(win.xmax-win.xmin)), sinewave);

Here is a results of my efforts.

The first thing that I can think of is a signal generator where the signal can be selected visually by walking through sub-windows. Changing resolution would result in signal frequency change obviously amplitude to amplitude. Another thing about several windows usage may be reading and displaying graphical information of several sensors like temperature. Each window could update in sequence. Hope this example will give some ideas to someone.

Comments are closed.