View previous topic :: View next topic |
Author |
Message |
barkerben
Joined: 19 Jan 2006 Posts: 22
|
Compass rose |
Posted: Tue Feb 28, 2006 9:12 am |
|
|
Hi,
I've been fiddling around trying to draw a compass on a 3310 LCD to replace the current text readout.
Drawing a static shape -lie the compass back - is no problem. The needle is a bit trickier though. I've been trying to draw it by using concentric circles of slowly increasing radii to work out which pixels to light up to draw the neccesary line.
It also aoccured to me it might be possible to draw a nice pointer, then use some sort of transformation matrix to make it point the direction you want before dumping it to the LCD...
any thoughts?
Ben |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 28, 2006 9:40 am |
|
|
Do a search for "Bressenham's algorithm". This is the best line drawing algorithm for this type of application. It is processor efficient, and given the two 'endpoints' of a line, works out what pixels have to be set to draw it. If you perhaps 'pre-calculate' the X,Y locations for the needle endpoint, you can use a simple 'lookup' to access these (rather than doing sin/cos calculations), and then this algorithm wil draw a line as required.
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 28, 2006 9:42 am |
|
|
Look at the glcd_line() function in the GLCD.C and GRAPHICS.C files.
These files are in c:\Program Files\Picc\Drivers
That line routine might be too slow. You might have to run
the PIC at 20 MHz or more, in order to get acceptable speed.
You'll have to look at it. |
|
|
barkerben
Joined: 19 Jan 2006 Posts: 22
|
|
Posted: Tue Feb 28, 2006 9:44 am |
|
|
Ah yes - this is what wikipedia has to say:
http://en.wikipedia.org/wiki/Bresenham's_line_algorithm
It looks ideal. I'm not sure whether a lookup table with enough entries for a compass (maybe 360 - depends on how many distinct lines can be drawn) would be more or less efficient that doing the trig, but I'll try it and let you know what happens.
Cheers,
Ben |
|
|
barkerben
Joined: 19 Jan 2006 Posts: 22
|
|
Posted: Tue Feb 28, 2006 9:49 am |
|
|
Hi Ttelmah,
When you refer to "that" routine, where you reffering to your post or to the one preceding it ...?
Cheers,
Ben |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 28, 2006 9:54 am |
|
|
I'd suggest that 180 angles would probably be enough. The lookup would only need work with integers, and can return directly an integer result. You should be able to lookup the endpoints, in perhaps 40 instruction times, while the trig, will probably involve a couple of thousand instructions+...
Best Wishes |
|
|
Guest
|
|
Posted: Tue Feb 28, 2006 9:58 am |
|
|
Ok - that sounds reasonable. This is a bit OT, but prersumable when trig is implemented on the PIC it is simply using a large lookup table...?
Thanks for all your help...
Ben |
|
|
Ttelmah Guest
|
|
Posted: Tue Feb 28, 2006 10:40 am |
|
|
Trig on the PIC, is done by successive approximation, in floating point. On a PIC16, you are talking about perhaps 10000 instructions to calculate a sin. On a PIC18, just under 7000 instructions (helped a bit by the hardware multiply). If you need a sin, and a cos, you can double this. Now for a simple pair of X/Y coordinates, a single lookup table, will give a 'X' value, and then if you offset the angle by 90 degrees, the same lookup table can be used for Y. 'EX_SINE.C', demonstrates using a 200 element table, to synthesise a sin wave on a D-A converter, and basically the table could be directly used. :-)
I don't refer to 'that routine'. PCM programmer does.
The basic Bressenham is as quick as it gets (it is used in the core of hardware line drawing systems). The key is how much you can trim it down (always draw the lines in one direction, simplify the sin/cos calculation etc.). This is the 'fun' bit...
Best Wishes |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Feb 28, 2006 10:44 am |
|
|
Bresenham's algorithm for lines and circles uses the mathematics of finite differences. To get a point on the compass arrow single double and triple width the initial few iterrations of the line drawing algorithm.To move from angles to pixel xy coordinates look at the cordic algorithm ( it computes coordinate transformations ( rotations through a prescribed angle) using additions and shifts only). The coordic will get you the sine cosine and the srt of (x^2+y^2) all at once in a few hundred machine instructions. Now if you need the whole compass rose to move to a heads up display ( a ships compass does this automatically to have the current bearing in the direction of the bow) stick with the cordic and rotate all the pixels forming the compass rose.
There are examples of the coordic and Bresenham's code in this forum. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 28, 2006 10:55 am |
|
|
Quote: | When you refer to "that" routine, where you referring to your post |
I was referring to the glcd_line() routine in the CCS driver files
GLCD.C and GRAPHICS.C:
Code: |
glcd_line(x1,y1,x2,y2,color)
// Draws a line from the first point to the second point
// with the given color.
// - color can be ON or OFF |
|
|
|
Guest
|
|
Posted: Thu Mar 02, 2006 2:44 pm |
|
|
I've implemented the simple bit - displaying a compass card. Strangely to get it circular on the 3310 I had to draw it as an elipse on the PC - suggesting the pixels aren't quite square.
I'm going to try to implement the line drawing part this weekend. I realise the biggist problem may be refferencing a single pixel - Generally I can address 84 collumns, but only 6 rows since I write a bits to the display each time.
I could possily use some sort of mask, but for that I need to know what the current display is to apply the mask to...
Oh well, hopefully I'll work it out :-p
Cheers,
Ben |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Thu Mar 02, 2006 2:52 pm |
|
|
Regarding pixels already on the display....
Read the contents of the screen RAM location, logically OR that with what you want to write, then rewrite this information to that same address. This is essentially what the "glcd" graphics lcd drivers do that come with the CCS compiler. |
|
|
Guest
|
|
Posted: Thu Mar 02, 2006 3:37 pm |
|
|
As far as I can see from the data sheets, I can't read the display ram directly prior to applying my OR mask. However, i could probably keep my own copy of the ram in an 84*6 array on the PIC, and then just update the LCD as needed. It's a bit wasetful of space, but should work...
http://www.amontec.com/lcd_controller_pcd8544.pdf |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Thu Mar 02, 2006 4:06 pm |
|
|
You're right!
I have difficulty understanding why the controller does NOT have a data read command. What you propose (keeping a local copy of screen contents within the PIC) is your only option. |
|
|
|