Skip to content
Browse files

Fixed bug in printing floating point numbers

Floating point numbers could not be printed due to the coordinate of
where text was printed not being updated.
  • Loading branch information...
1 parent 608c63f commit 1e578dee94ac7ece1ccf254c00854c552e01847a @TCWORLD committed Feb 7, 2013
View
BIN Downloads/gLCD v3_5.zip
Binary file not shown.
View
5 README
@@ -17,9 +17,12 @@ The gLCD folder contains a copy of the current code version to allow the library
---------------------------------------------------------------------------------------
-Current Version 3.4
+Current Version 3.5
---------------------------------------------------------------------------------------
+Version 3.5 fixes a bug that prevented floating point (decimal) numbers being printed.
+
+
---------------------------------------------------------------------------------------
Version 3.3 onwards support rotating screens by either 0, 90, 180 or 270 degrees clockwise.
View
304 Version 3_5/examples/BasicFunctions/BasicFunctions.pde
@@ -0,0 +1,304 @@
+/*
+ gLCD Library Example 1:
+
+ This example shows how to use the basic functions: Line, Plot, Box, Circle, Print, SetForeColour, and SetBackColour.
+
+ gLCD should work for all Nokia Clone 128x128 screens which have the
+ Epson or Phillips controller chip.
+*/
+
+#include <gLCD.h>
+
+//You can use these variables to set the pin numbers
+const char RST = 8;
+const char CS = 9;
+const char Clk = 13;
+const char Data = 11;
+
+/*Create an instance of the display. Lets call it 'graphic'.
+ There are four variables,
+ which define which pins the LCD is connected too.
+ these are:
+ Reset, Chip Select, Clock, Data.
+
+ A fifth variable 'speed' can be included as 0 or 1, which controls whether to enter high speed mode (see below).
+ If the fifth variable is omitted (i.e. only the first four are given), normal speed mode is implied.
+
+ gLCD graphic(RST,CS,Clk,Data [,speed]);
+
+ Note, it is also possible to enable a high speed mode which increases the speed of the display
+ by a factor of >5. This is done through the library bypassing the digitalWrite function and
+ directly addressing port registers.
+ For the Due, High speed mode increases speed to such an extent that this example completes before you can blink.
+
+ Please note that while this doesn't affect how you use the library (it is all handled internally),
+ it is possible that it may run too fast for your display and thus the display will appear to not work.
+ This is UNLIKELY to happen, and I have checked with several displays which all worked fine.
+
+ As of version 2.4 nothing special needs to be done to use this high speed mode, so I am now mentioning
+ it is the example file.
+
+*/
+
+//For normal speed, use:
+//gLCD graphic(RST,CS,Clk,Data,NORMAL_SPEED); //Normal speed
+//For high speed, use:
+gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed
+
+
+void setup() {
+ /*Display needs to be initialised. You only need to do this once,
+ You may have to press the Arduino reset button after uploading
+ your code as the screen may fail to startup otherwise
+
+ The first two variables in the begin() call specify where on the screen
+ origin is. On some screens the first one or two rows/cols of
+ pixels aren't visible, so begin(X,Y,,) allows all X and Y co-ords
+ to be shifted slightly.
+
+ The third variable specifies whether the colours are inverted.
+ If the White background is Black on your screen, set this to a 1
+ Else leave it as a zero
+
+ The fourth variable is the driver to use you can choose from. There are 6 drivers:
+ EPSON (or) EPSON_4 (both are the same)
+ EPSON_5
+ PHILLIPS_0
+ PHILLIPS_1
+ PHILLIPS_2
+ PHILLIPS_3
+
+
+ To determine the offset (x,y) coordinate, run this example sketch. It will print a 10px x 10px red box
+ in the top left corner of the screen. If that boxes outline does not line up with the corner, try
+ using the offsets. A positive x will shift the screen to the right, negative x to the left. A positve Y
+ will shift the display down, and a negative Y will shift it up.
+
+
+ For an Epson Screen:
+ */
+
+ //This
+ graphic.begin(0,0,0,EPSON); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_4); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_5); //16bit mode Epson - suits some rare screens.
+
+ //For a Phillips Screen:
+ //This
+ //graphic.begin(0,0,0,PHILLIPS_0); //Normal X direction
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_1); //Revesed X direction.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_2); //Normal X direction, Mirrored.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_3); //Revesed X direction, Mirrored.
+
+ graphic.setBackColour(GLCD_LIME); //set the background to lime colour.
+ graphic.Clear();
+
+ /*If you can't see the colours properly, then uncomment the
+ graphic.Contrast() function.
+ If the Screen is too dark, or you cant see anything send a value >0x2B (>0x30 for Phillips). If you cant see all
+ the different colours distinctly on the test pattern, send a value <0x2B (<0x30 for Phillips). The default values
+ should work for many screens, so you may not have to use this at all.
+
+ Range for phillips: -0x3F to 0x3F
+ Range for EPSON: 0x00 to 0x3F
+ */
+
+ //graphic.Contrast(0x2B);
+}
+void loop() {
+ /*Lets draw a box...
+
+ First we set the background colour and foreground colour
+ We use the SetBackColour function to do this.
+ The function takes three bytes, which are: Red, Green, Blue.
+ Each of these is a 4 bit number where 0 = off, 15 = fully on.
+ */
+
+ //We want a white background, so that would be 15 for each variable
+ graphic.setBackColour(15,15,15);
+
+ //We want a red foreground, so red will be 15 and the others 0
+ graphic.setForeColour(15,0,0);
+
+ /*Now We draw our box. Lets use the Box() function.
+ Box( X1, Y1, X2, Y2, format) takes 5 variables.
+
+ The first two are: X1, Y1. These are bytes which represent the (x,y) co-ord where the box will start
+
+ The second two are: X2, Y2. These bytes represent the (x,y) co-ord where the box will end. NOTE: This coodinate will also be included in the box
+
+ The final one is: format. This controls how the box will look (b7..b3 are ignored)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 1 | x | Draws a box with just a border of colour BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 1 | x | Draws a box with just a border of colour ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 0 | Draws a box with border in BackColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 0 | Draws a box with border in ForeColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 1 | Draws a box with border in BackColour and fill inside it with ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 1 | Draws a box with border in ForeColour and fill inside it with ForeColour
+
+ Or you can use one of the predefined constants:
+ OutlineBackColour = 0b010
+ OutlineForeColour = 0b110
+ SolidBackColour = 0b000
+ BorderForeColour_FillBackColour = 0b100
+ BorderBackColour_FillForeColour = 0b001
+ SolidForeColour = 0b101
+
+
+ Lets draw a box which starts from (10,10) and is 100 pixes square. So, X1 = 10,
+ Y1 = 10,
+ X2 = 10 + 99, <- Because X2,Y2 will be part of the box
+ Y2 = 10 + 99
+ It will have a border coloured Red, and be filled with the background colour. So, 'format' = 4
+ */
+ graphic.Box(10,10,109,109,4);
+ //Or This:
+ //graphic.Box(10,10,109,109,BorderForeColour_FillBackColour);
+
+ //Inside is another box filled in the foreground colour
+ graphic.Box(20,20,99,99,5);
+ //Or This:
+ //graphic.Box(20,20,99,99,SolidForeColour);
+
+ /* Next we will write Hello in the centre. For this we need to use the print() function. This behaves exactly like Serial.print() only it prints to the screen not the
+ serial port.
+
+ First though we need to setup the text. There are two functions to do this.
+ setCoordinate(X,Y);
+ and
+ setFont(Font);
+
+ In setCoordinate(X,Y), we set the co-ordinates of where the text will be placed on the screen - (X,Y) pixels denotes the top left corner.
+ NOTE: Currently there is no text wrap so strings that dont fit on the screen will be clipped.
+ However you can use a '\n' character to print the characters following it on a new line directly below.
+
+ Then, in setFont(Font), we set the Font. This controls the vertical and horizontal scaling of the text, and also whether it has a solid or transparent background.
+ Font bits have the following meaning: (b7..b4 are ignored - maybe future use)
+
+ b2 | b2 | b1 | b0 | Meaning
+ ----+----+----+----+-----------------------------------------------
+ 0 | x | x | x | Text will be truncated if too long for screen
+ ----+----+----+----+-----------------------------------------------
+ 1 | x | x | x | Text will be wrapped onto new line if too long
+ ----+----+----+----+-----------------------------------------------
+ x | 0 | x | x | Text has transparent background
+ ----+----+----+----+-----------------------------------------------
+ x | 1 | x | x | Text has solid background
+ ----+----+----+----+-----------------------------------------------
+ x | x | 0 | 0 | Text normal. (6 x 8 pixels)
+ ----+----+----+----+-----------------------------------------------
+ x | x | 0 | 1 | Text Wide. (12 x 8 pixels)
+ ----+----+----+----+-----------------------------------------------
+ x | x | 1 | 0 | Text Tall. (6 x 16 pixels)
+ ----+----+----+----+-----------------------------------------------
+ x | x | 1 | 1 | Text Tall and Wide. (12 x 16 pixels)
+
+ Or you can use one of the predefined constants:
+ Normal_ClearBG = 0b000 = 0
+ Wide_ClearBG = 0b001 = 1
+ Tall_ClearBG = 0b010 = 2
+ Large_ClearBG = 0b011 = 3
+ Normal_SolidBG = 0b100 = 4
+ Wide_SolidBG = 0b101 = 5
+ Tall_SolidBG = 0b110 = 6
+ Large_SolidBG = 0b111 = 7
+ Normal_ClearBG_Wrap = 0b1000 = 8
+ Wide_ClearBG_Wrap = 0b1001 = 9
+ Tall_ClearBG_Wrap = 0b1010 = 10
+ Large_ClearBG_Wrap = 0b1011 = 11
+ Normal_SolidBG_Wrap = 0b1100 = 12
+ Wide_SolidBG_Wrap = 0b1101 = 13
+ Tall_SolidBG_Wrap = 0b1110 = 14
+ Large_SolidBG_Wrap = 0b1111 = 15
+
+ We then finally call the print function with our text or variable, e.g.
+ graphic.print("Some Text");
+ See print() in the Arduino Reference for more details.
+ */
+ graphic.setForeColour(0,0,15); //Text is coloured Blue
+ graphic.setFont(4); //normal size text, solid background.
+ //graphic.setFont(Normal_SolidBG); //normal size text, solid background.
+ graphic.setCoordinate(40,40);
+ graphic.print("Hello\nWorld"); //Hello and World will be printed on seperate lines as governed by the newline character '\n'
+
+ graphic.setFont(12); //normal size text, solid background. Wrap string to new line if needed
+ //graphic.setFont(Normal_SolidBG_Wrap); //normal size text, solid background. Wrap string to new line if needed
+ graphic.setCoordinate(0,112);
+ graphic.print("This string is too long for a single line"); //The string is too long for a single line, but by selecting one of the '_Wrap' fonts, it will be automatically split onto new lines.
+
+ /* Now lets double underline the text twice. Each normal character takes up 6 x 8 pixels, so we need to draw a line 8+9 pixels below the top of the text as there are two lines.
+ The line is 6*5 = 30px long. And a second of the same length which is 11 pixels below the top of the text.
+
+ For this we can use the Line() Function.
+ Line(X1,X2,Y1,Y2,Colour) takes five variables
+
+ Firstly X1 and Y1 are both unsigned chars which are where the line starts.
+
+ The second two are: X2,Y2. These are the last point on the line.
+
+ Lastly: Colour. This defines whether the line should be in Foreground colour (Colour = 1) or Background colour (Colour = 0)
+ */
+ graphic.Line(40,57,69,57,4); // The lines will be Blue as that was the last foreground colour that was set.
+ graphic.Line(40,59,69,59,4);
+
+ /* The next function is Circle().
+ Circle(X1,Y1,Radius,Format) takes four variables
+
+ The first two are: X1, Y1. These are bytes which represent the (x,y) co-ord of the centre of the circle.
+
+ The next is: Radius. This is the radius of the circle in pixels.
+
+ The final one is: Format. This controls how the Circle will look (b7..b3 are ignored)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 1 | x | Draws a Circle with just a border of colour BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 1 | x | Draws a Circle with just a border of colour ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 0 | Draws a Circle with border in BackColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 0 | Draws a Circle with border in ForeColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 1 | Draws a Circle with border in BackColour and fill inside it with ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 1 | Draws a Circle with border in ForeColour and fill inside it with ForeColour
+ Or you can use one of the predefined constants:
+ OutlineBackColour = 0b010
+ OutlineForeColour = 0b110
+ SolidBackColour = 0b000
+ BorderForeColour_FillBackColour = 0b100
+ BorderBackColour_FillForeColour = 0b001
+ SolidForeColour = 0b101
+ */
+ graphic.Circle(66,74,15,4); //Draw circle of radius 10px, filled with the background colour
+ //Or:
+ //graphic.Circle(66,74,15,BorderForeColour_FillBackColour); //Draw circle of radius 10px, filled with the background colour
+
+ /* The last basic function is Plot(). This simply sets the colour of the pixel at (x,y) to the current foreground colour.
+ Plot(X,Y) takes three variables.
+
+ X and Y are the co-odinate where the dot is drawn.
+
+ Colour defines whether the line should be in Foreground colour (Colour = 3) or Background colour (Colour = 0)
+ */
+ for (int i = 15;i < 19;i++){
+ for (int j = 17;j < 21;j++){
+ graphic.Plot((i*4), (j*4),3); //Draw a grid of 16 dots.
+ }
+ }
+
+ while(1); //Finished
+}
View
176 Version 3_5/examples/ImageRotation/ImageRotation.pde
@@ -0,0 +1,176 @@
+/*
+ gLCD Library Example 3:
+
+ This example shows how to use the setRotation() function to rotate the screen.
+
+ gLCD should work for all Nokia Clone 128x128 screens which have the
+ Epson or Phillips controller chip.
+*/
+
+#include <gLCD.h>
+
+//You can use these variables to set the pin numbers
+const char RST = 8;
+const char CS = 9;
+const char Clk = 13;
+const char Data = 11;
+
+/*Create an instance of the display. Lets call it 'graphic'.
+ There are four variables,
+ which define which pins the LCD is connected too.
+ these are:
+ Reset, Chip Select, Clock, Data.
+
+ A fifth variable 'speed' can be included as 0 or 1, which controls whether to enter high speed mode (see below).
+ If the fifth variable is omitted (i.e. only the first four are given), normal speed mode is implied.
+
+ gLCD graphic(RST,CS,Clk,Data [,speed]);
+
+ Note, it is also possible to enable a high speed mode which increases the speed of the display
+ by a factor of >5. This is done through the library bypassing the digitalWrite function and
+ directly addressing port registers.
+ For the Due, High speed mode increases speed to such an extent that this example completes before you can blink.
+
+ Please note that while this doesn't affect how you use the library (it is all handled internally),
+ it is possible that it may run too fast for your display and thus the display will appear to not work.
+ This is UNLIKELY to happen, and I have checked with several displays which all worked fine.
+
+ As of version 2.4 nothing special needs to be done to use this high speed mode, so I am now mentioning
+ it is the example file.
+
+*/
+//For normal speed, use:
+//gLCD graphic(RST,CS,Clk,Data,NORMAL_SPEED); //Normal speed
+
+//For high speed, use:
+gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed
+
+
+void setup() {
+ /*Display needs to be initialised. You only need to do this once,
+ You may have to press the Arduino reset button after uploading
+ your code as the screen may fail to startup otherwise
+
+ The first two variables in the begin() call specify where on the screen
+ origin is. On some screens the first one or two rows/cols of
+ pixels aren't visible, so begin(X,Y,,) allows all X and Y co-ords
+ to be shifted slightly.
+
+ The third variable specifies whether the colours are inverted.
+ If the White background is Black on your screen, set this to a 1
+ Else leave it as a zero
+
+ The fourth variable is the driver to use you can choose from. There are 6 drivers:
+ EPSON (or) EPSON_4 (both are the same)
+ EPSON_5
+ PHILLIPS_0
+ PHILLIPS_1
+ PHILLIPS_2
+ PHILLIPS_3
+
+ For an Epson Screen:
+ */
+
+ //This
+ graphic.begin(0,0,0,EPSON); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_4); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_5); //16bit mode Epson - suits some rare screens.
+
+ //For a Phillips Screen:
+ //This
+ //graphic.begin(0,0,0,PHILLIPS_0); //Normal X direction
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_1); //Revesed X direction.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_2); //Normal X direction, Mirrored.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_3); //Revesed X direction, Mirrored.
+
+ /*If you can't see the colours properly, then uncomment the
+ graphic.Contrast() function.
+ If the Screen is too dark, or you cant see anything send a value >0x2B (>0x30 for Phillips). If you cant see all
+ the different colours distinctly on the test pattern, send a value <0x2B (<0x30 for Phillips). The default values
+ should work for many screens, so you may not have to use this at all.
+
+ Range for phillips: -0x3F to 0x3F
+ Range for EPSON: 0x00 to 0x3F
+ */
+
+ //graphic.Contrast(0x2B);
+}
+void loop(){
+ static ImageRotation rotation = ROTATION_0; //Setup a variable to store the current rotation
+ graphic.setRotation(rotation++); //set the current rotation, then increment it for next time
+
+ //We want a white background, so that would be 15 for each variable
+ graphic.setBackColour(15,15,15);
+
+ /* Next we will write Hello in the top left corner. For this we need to use the print() function. This behaves exactly like Serial.print() only it prints to the screen not the
+ serial port.
+
+ First though we need to setup the text. There are two functions to do this.
+ setCoordinate(X,Y);
+ and
+ setFont(Font);
+
+ In setCoordinate(X,Y), we set the co-ordinates of where the text will be placed on the screen - (X,Y) pixels denotes the top left corner.
+ NOTE: Currently there is no text wrap so strings that dont fit on the screen will be clipped.
+ However you can use a '\n' character to print the characters following it on a new line directly below.
+
+ Then, in setFont(Font), we set the Font. This controls the vertical and horizontal scaling of the text, and also whether it has a solid or transparent background.
+ Font bits have the following meaning: (b7..b3 are ignored - maybe future use)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+---------------------------------------
+ 0 | x | x | Text has transparent background
+ ----+----+----+---------------------------------------
+ 1 | x | x | Text has solid background
+ ----+----+----+---------------------------------------
+ x | 0 | 0 | Text normal. (6 x 8 pixels)
+ ----+----+----+---------------------------------------
+ x | 0 | 1 | Text Wide. (12 x 8 pixels)
+ ----+----+----+---------------------------------------
+ x | 1 | 0 | Text Tall. (6 x 16 pixels)
+ ----+----+----+---------------------------------------
+ x | 1 | 1 | Text Tall and Wide. (12 x 16 pixels)
+
+ Or you can use one of the predefined constants:
+ Normal_ClearBG = 0b000 = 0
+ Wide_ClearBG = 0b001 = 1
+ Tall_ClearBG = 0b010 = 2
+ Large_ClearBG = 0b011 = 3
+ Normal_SolidBG = 0b100 = 4
+ Wide_SolidBG = 0b101 = 5
+ Tall_SolidBG = 0b110 = 6
+ Large_SolidBG = 0b111 = 7
+ Normal_ClearBG_Wrap = 0b1000 = 8
+ Wide_ClearBG_Wrap = 0b1001 = 9
+ Tall_ClearBG_Wrap = 0b1010 = 10
+ Large_ClearBG_Wrap = 0b1011 = 11
+ Normal_SolidBG_Wrap = 0b1100 = 12
+ Wide_SolidBG_Wrap = 0b1101 = 13
+ Tall_SolidBG_Wrap = 0b1110 = 14
+ Large_SolidBG_Wrap = 0b1111 = 15
+
+
+ We then finally call the print function with our text or variable, e.g.
+ graphic.print("Some Text");
+ See print() in the Arduino Reference for more detains.
+ */
+ graphic.setForeColour(0,0,15); //Text is coloured Blue
+ graphic.setFont(Normal_SolidBG); //normal size text, solid background.
+ graphic.setCoordinate(0,0);
+ graphic.print("Hello\nWorld!"); //Hello and World will be printed on seperate lines as governed by the newline character '\n'
+
+ //We want a red foreground
+ graphic.setForeColour(GLCD_RED);
+ for (int i = 13;i < 21;i++){
+ for (int j = 13;j < 21;j++){
+ graphic.Plot((i*5), (j*5),3); //Draw a grid of 64 dots.
+ }
+ }
+
+ delay(2000); //wait 2 seconds, then repeat.
+}
View
111 Version 3_5/examples/TestPattern/TestPattern.pde
@@ -0,0 +1,111 @@
+/*
+ gLCD Library Example 2:
+
+ This example shows you how to create an instance of the display,
+ connect it to the correct pins, and then display the built in
+ Test Pattern.
+
+ gLCD should work for all Nokia Clone 128x128 screens which have the
+ Epson controller chip.
+*/
+
+#include <gLCD.h>
+
+//You can use these variables to set the pin numbers
+const char RST = 8;
+const char CS = 9;
+const char Clk = 13;
+const char Data = 11;
+
+/*Create an instance of the display. Lets call it 'graphic'.
+ There are four variables,
+ which define which pins the LCD is connected too.
+ these are:
+ Reset, Chip Select, Clock, Data.
+
+ A fifth variable 'speed' can be included as 0 or 1, which controls whether to enter high speed mode (see below).
+ If the fifth variable is omitted (i.e. only the first four are given), normal speed mode is implied.
+
+ gLCD graphic(RST,CS,Clk,Data [,speed]);
+
+ Note, it is also possible to enable a high speed mode which increases the speed of the display
+ by a factor of >5. This is done through the library bypassing the digitalWrite function and
+ directly addressing port registers.
+ For the Due, High speed mode increases speed to such an extent that this example completes before you can blink.
+
+ Please note that while this doesn't affect how you use the library (it is all handled internally),
+ it is possible that it may run too fast for your display and thus the display will appear to not work.
+ This is UNLIKELY to happen, and I have checked with several displays which all worked fine.
+
+ As of version 2.4 nothing special needs to be done to use this high speed mode, so I am now mentioning
+ it is the example file.
+
+*/
+//For normal speed, use:
+gLCD graphic(RST,CS,Clk,Data,NORMAL_SPEED); //Normal speed
+
+//For high speed, use:
+// gLCD graphic(RST,CS,Clk,Data,HIGH_SPEED); //High speed
+
+
+void setup() {
+ /*Display needs to be initialised. You only need to do this once,
+ You may have to press the Arduino reset button after uploading
+ your code as the screen may fail to startup otherwise
+
+ The first two variables in the begin() call specify where on the screen
+ origin is. On some screens the first one or two rows/cols of
+ pixels aren't visible, so begin(X,Y,,) allows all X and Y co-ords
+ to be shifted slightly. (0,2) works well for both my screens.
+
+ The third variable specifies whether the colours are inverted.
+ If the White background is Black on your screen, set this to a 1
+ Else leave it as a zero
+
+ The fourth variable is the driver to use you can choose from. There are 6 drivers:
+ EPSON (or) EPSON_4 (both are the same)
+ EPSON_5
+ PHILLIPS_0
+ PHILLIPS_1
+ PHILLIPS_2
+ PHILLIPS_3
+
+ For an Epson Screen:
+ */
+
+ //This
+ graphic.begin(0,0,0,EPSON); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_4); //Normal Epson
+ //or
+ //graphic.begin(0,0,0,EPSON_5); //16bit mode Epson - suits some rare screens.
+
+ //For a Phillips Screen:
+ //This
+ //graphic.begin(0,0,0,PHILLIPS_0); //Normal X direction
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_1); //Revesed X direction.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_2); //Normal X direction, Mirrored.
+ //or
+ //graphic.begin(0,0,0,PHILLIPS_3); //Revesed X direction, Mirrored.
+
+
+
+ /*If you can't see the colours properly, then uncomment the
+ graphic.Contrast() function.
+ If the Screen is too dark, or you cant see anything send a value >0x2B (>0x30 for Phillips). If you cant see all
+ the different colours distinctly on the test pattern, send a value <0x2B (<0x30 for Phillips). The default values
+ should work for many screens, so you may not have to use this at all.
+
+ Range for phillips: -0x3F to 0x3F
+ Range for EPSON: 0x00 to 0x3F
+ */
+
+ //graphic.Contrast(0x2B);
+}
+void loop() {
+ //Print out the test pattern.
+ graphic.testPattern();
+ while(1); //Finished
+}
View
1,207 Version 3_5/gLCD.cpp
@@ -0,0 +1,1207 @@
+/*
+ Sparkfun Nokia knockoff screen 128x128 controller. Should work with (all) screens.
+
+ Code written by Thomas Carpenter (2011)
+
+ ==================================================================================================
+ Current Library Version: 3.5
+
+ See header file for function descriptions and ChangeLog
+
+*/
+#if ARDUINO >= 100
+ #include "Arduino.h"
+#else
+ #include "WProgram.h"
+#endif
+#include "gLCD.h"
+#ifndef _LIB_SAM_
+#define PGMSPACE PROGMEM
+#include <avr/pgmspace.h>
+#else
+#define PGMSPACE const
+#endif
+
+//Character Database store
+
+//This is how many custom characters you have added to the end of the map. There are no more than 128 allowed.
+#define numberOfCustomCharacters 9
+PGMSPACE DEFAULT_DATA_TYPE charData[96 + numberOfCustomCharacters][5] = {
+ {0x00 , 0x00 , 0x00 , 0x00 , 0x00 }, // 32 = <space>
+ {0x00 , 0x06 , 0x5F , 0x06 , 0x00 }, // 33 = !
+ {0x07 , 0x03 , 0x00 , 0x07 , 0x03 }, // 34 = "
+ {0x24 , 0x7E , 0x24 , 0x7E , 0x24 }, // 35 = #
+ {0x24 , 0x2B , 0x6A , 0x12 , 0x00 }, // 36 = $
+ {0x63 , 0x13 , 0x08 , 0x64 , 0x63 }, // 37 = %
+ {0x36 , 0x49 , 0x56 , 0x20 , 0x50 }, // 38 = &
+ {0x00 , 0x07 , 0x03 , 0x00 , 0x00 }, // 39 = '
+ {0x00 , 0x3E , 0x41 , 0x00 , 0x00 }, // 40 = (
+ {0x00 , 0x41 , 0x3E , 0x00 , 0x00 }, // 41 = )
+ {0x08 , 0x3E , 0x1C , 0x3E , 0x08 }, // 42 = *
+ {0x08 , 0x08 , 0x3E , 0x08 , 0x08 }, // 43 = +
+ {0x00 , 0xE0 , 0x60 , 0x00 , 0x00 }, // 44 = ,
+ {0x08 , 0x08 , 0x08 , 0x08 , 0x08 }, // 45 = -
+ {0x00 , 0x60 , 0x60 , 0x00 , 0x00 }, // 46 = .
+ {0x20 , 0x10 , 0x08 , 0x04 , 0x02 }, // 47 = /
+ {0x3E , 0x51 , 0x49 , 0x45 , 0x3E }, // 48 = 0
+ {0x00 , 0x42 , 0x7F , 0x40 , 0x00 }, // 49 = 1
+ {0x62 , 0x51 , 0x49 , 0x49 , 0x46 }, // 50 = 2
+ {0x22 , 0x49 , 0x49 , 0x49 , 0x36 }, // 51 = 3
+ {0x18 , 0x14 , 0x12 , 0x7F , 0x10 }, // 52 = 4
+ {0x2F , 0x49 , 0x49 , 0x49 , 0x31 }, // 53 = 5
+ {0x3C , 0x4A , 0x49 , 0x49 , 0x30 }, // 54 = 6
+ {0x01 , 0x71 , 0x09 , 0x05 , 0x03 }, // 55 = 7
+ {0x36 , 0x49 , 0x49 , 0x49 , 0x36 }, // 56 = 8
+ {0x06 , 0x49 , 0x49 , 0x29 , 0x1E }, // 57 = 9
+ {0x00 , 0x6C , 0x6C , 0x00 , 0x00 }, // 58 = :
+ {0x00 , 0xEC , 0x6C , 0x00 , 0x00 }, // 59 = ;
+ {0x08 , 0x14 , 0x22 , 0x41 , 0x00 }, // 60 = <
+ {0x24 , 0x24 , 0x24 , 0x24 , 0x24 }, // 61 = =
+ {0x00 , 0x41 , 0x22 , 0x14 , 0x08 }, // 62 = >
+ {0x02 , 0x01 , 0x59 , 0x09 , 0x06 }, // 63 = ?
+ {0x3E , 0x41 , 0x5D , 0x55 , 0x1E }, // 64 = @
+ {0x7E , 0x09 , 0x09 , 0x09 , 0x7E }, // 65 = A
+ {0x7F , 0x49 , 0x49 , 0x49 , 0x36 }, // 66 = B
+ {0x3E , 0x41 , 0x41 , 0x41 , 0x22 }, // 67 = C
+ {0x7F , 0x41 , 0x41 , 0x41 , 0x3E }, // 68 = D
+ {0x7F , 0x49 , 0x49 , 0x49 , 0x41 }, // 69 = E
+ {0x7F , 0x09 , 0x09 , 0x09 , 0x01 }, // 70 = F
+ {0x3E , 0x41 , 0x49 , 0x49 , 0x7A }, // 71 = G
+ {0x7F , 0x08 , 0x08 , 0x08 , 0x7F }, // 72 = H
+ {0x00 , 0x41 , 0x7F , 0x41 , 0x00 }, // 73 = I
+ {0x30 , 0x40 , 0x40 , 0x40 , 0x3F }, // 74 = J
+ {0x7F , 0x08 , 0x14 , 0x22 , 0x41 }, // 75 = K
+ {0x7F , 0x40 , 0x40 , 0x40 , 0x40 }, // 76 = L
+ {0x7F , 0x02 , 0x04 , 0x02 , 0x7F }, // 77 = M
+ {0x7F , 0x02 , 0x04 , 0x08 , 0x7F }, // 78 = N
+ {0x3E , 0x41 , 0x41 , 0x41 , 0x3E }, // 79 = O
+ {0x7F , 0x09 , 0x09 , 0x09 , 0x06 }, // 80 = P
+ {0x3E , 0x41 , 0x51 , 0x21 , 0x5E }, // 81 = Q
+ {0x7F , 0x09 , 0x09 , 0x19 , 0x66 }, // 82 = R
+ {0x26 , 0x49 , 0x49 , 0x49 , 0x32 }, // 83 = S
+ {0x01 , 0x01 , 0x7F , 0x01 , 0x01 }, // 84 = T
+ {0x3F , 0x40 , 0x40 , 0x40 , 0x3F }, // 85 = U
+ {0x1F , 0x20 , 0x40 , 0x20 , 0x1F }, // 86 = V
+ {0x3F , 0x40 , 0x3C , 0x40 , 0x3F }, // 87 = W
+ {0x63 , 0x14 , 0x08 , 0x14 , 0x63 }, // 88 = X
+ {0x07 , 0x08 , 0x70 , 0x08 , 0x07 }, // 89 = Y
+ {0x71 , 0x49 , 0x45 , 0x43 , 0x00 }, // 90 = Z
+ {0x00 , 0x7F , 0x41 , 0x41 , 0x00 }, // 91 = [
+ {0x02 , 0x04 , 0x08 , 0x10 , 0x20 }, // 92 = <backslash>
+ {0x00 , 0x41 , 0x41 , 0x7F , 0x00 }, // 93 = ]
+ {0x04 , 0x02 , 0x01 , 0x02 , 0x04 }, // 94 = ^
+ {0x80 , 0x80 , 0x80 , 0x80 , 0x80 }, // 95 = _
+ {0x00 , 0x03 , 0x07 , 0x00 , 0x00 }, // 96 = `
+ {0x20 , 0x54 , 0x54 , 0x54 , 0x78 }, // 97 = a
+ {0x7F , 0x44 , 0x44 , 0x44 , 0x38 }, // 98 = b
+ {0x38 , 0x44 , 0x44 , 0x44 , 0x28 }, // 99 = c
+ {0x38 , 0x44 , 0x44 , 0x44 , 0x7F }, // 100 = d
+ {0x38 , 0x54 , 0x54 , 0x54 , 0x18 }, // 101 = e
+ {0x08 , 0x7E , 0x09 , 0x09 , 0x00 }, // 102 = f
+ {0x18 , 0xA4 , 0xA4 , 0xA4 , 0x7C }, // 103 = g
+ {0x7F , 0x04 , 0x04 , 0x78 , 0x00 }, // 104 = h
+ {0x00 , 0x00 , 0x7D , 0x00 , 0x00 }, // 105 = i
+ {0x40 , 0x80 , 0x84 , 0x7D , 0x00 }, // 106 = j
+ {0x7F , 0x10 , 0x28 , 0x44 , 0x00 }, // 107 = k
+ {0x00 , 0x00 , 0x7F , 0x40 , 0x00 }, // 108 = l
+ {0x7C , 0x04 , 0x18 , 0x04 , 0x78 }, // 109 = m
+ {0x7C , 0x04 , 0x04 , 0x78 , 0x00 }, // 110 = n
+ {0x38 , 0x44 , 0x44 , 0x44 , 0x38 }, // 111 = o
+ {0xFC , 0x44 , 0x44 , 0x44 , 0x38 }, // 112 = p
+ {0x38 , 0x44 , 0x44 , 0x44 , 0xFC }, // 113 = q
+ {0x44 , 0x78 , 0x44 , 0x04 , 0x08 }, // 114 = r
+ {0x08 , 0x54 , 0x54 , 0x54 , 0x20 }, // 115 = s
+ {0x04 , 0x3E , 0x44 , 0x24 , 0x00 }, // 116 = t
+ {0x3C , 0x40 , 0x20 , 0x7C , 0x00 }, // 117 = u
+ {0x1C , 0x20 , 0x40 , 0x20 , 0x1C }, // 118 = v
+ {0x3C , 0x60 , 0x30 , 0x60 , 0x3C }, // 119 = w
+ {0x6C , 0x10 , 0x10 , 0x6C , 0x00 }, // 120 = x
+ {0x9C , 0xA0 , 0x60 , 0x3C , 0x00 }, // 121 = y
+ {0x64 , 0x54 , 0x54 , 0x4C , 0x00 }, // 122 = z
+ {0x08 , 0x3E , 0x41 , 0x41 , 0x00 }, // 123 = {
+ {0x00 , 0x00 , 0x7F , 0x00 , 0x00 }, // 124 = |
+ {0x00 , 0x41 , 0x41 , 0x3E , 0x08 }, // 125 = }
+ {0x02 , 0x01 , 0x02 , 0x01 , 0x00 }, // 126 = ~
+
+ //Custom Non-ASCII charaters
+ //Add more lines at the end to generate custom characters.
+
+ {0x02 , 0x6F , 0x1A , 0x30 , 0x6E }, // 127 = Shuffle
+ {0x3C , 0x62 , 0x47 , 0x62 , 0x38 }, // -128 = Repeat
+ {0x3E , 0x3E , 0x3E , 0x3E , 0x3E }, // -127 = Stop
+ {0x00 , 0x7F , 0x3E , 0x1C , 0x08 }, // -126 = Play
+ {0x3E , 0x3E , 0x00 , 0x3E , 0x3E }, // -125 = Pause
+ {0x7F , 0x3E , 0x1C , 0x08 , 0x7F }, // -124 = Skip
+ {0x1C , 0x3E , 0x7F , 0x00 , 0x1C }, // -123 = Volume
+ {0x1C , 0x3E , 0x7F , 0x00 , 0x00 }, // -122 = Mute
+ {0x3C , 0x60 , 0x4F , 0x60 , 0x3C }, // -121 = Power
+};
+
+gLCD::gLCD(DEFAULT_DATA_TYPE RS, DEFAULT_DATA_TYPE CS, DEFAULT_DATA_TYPE SCLK, DEFAULT_DATA_TYPE SDATA, SpeedMode speed){
+ _fast = speed;
+
+ pinMode(RS, OUTPUT);
+ _RS = RS;
+ pinMode(CS, OUTPUT);
+ _CS = CS;
+ pinMode(SCLK, OUTPUT);
+ _SCLK = SCLK;
+ pinMode(SDATA, OUTPUT);
+ _SDATA = SDATA;
+
+ if(speed){
+#ifndef _LIB_SAM_
+ unsigned char RSport = digitalPinToPort(RS);
+ unsigned char CSport = digitalPinToPort(CS);
+ unsigned char SCLKport = digitalPinToPort(SCLK);
+ unsigned char SDATAport = digitalPinToPort(SDATA);
+
+ if (( RSport == NOT_A_PIN) ||
+ ( CSport == NOT_A_PIN) ||
+ ( SCLKport == NOT_A_PIN) ||
+ (SDATAport == NOT_A_PIN) )
+ {
+ _fast = 0; //Not a correct register, so use digitalWrite
+ } else {
+ _RS_PORT = portOutputRegister(RSport);
+ _CS_PORT = portOutputRegister(CSport);
+ _SCLK_PORT = portOutputRegister(SCLKport);
+ _SDATA_PORT = portOutputRegister(SDATAport);
+ _RS_HIGH = digitalPinToBitMask(RS);
+ _RS_LOW = ~_RS_HIGH;
+ _CS_HIGH = digitalPinToBitMask(CS);
+ _CS_LOW = ~_CS_HIGH;
+ _SCLK_HIGH = digitalPinToBitMask(SCLK);
+ _SCLK_LOW = ~_SCLK_HIGH;
+ _SDATA_HIGH = digitalPinToBitMask(SDATA);
+ _SDATA_LOW = ~_SDATA_HIGH;
+ }
+#else
+ if ((g_APinDescription[RS].ulPinType == PIO_NOT_A_PIN) ||
+ (g_APinDescription[CS].ulPinType == PIO_NOT_A_PIN) ||
+ (g_APinDescription[SCLK].ulPinType == PIO_NOT_A_PIN) ||
+ (g_APinDescription[SDATA].ulPinType == PIO_NOT_A_PIN) )
+ {
+ _fast = 0; //Not a correct register, so use digitalWrite
+ } else {
+ _RS_PORT = g_APinDescription[RS].pPort;
+ _CS_PORT = g_APinDescription[CS].pPort;
+ _SCLK_PORT = g_APinDescription[SCLK].pPort;
+ _SDATA_PORT = g_APinDescription[SDATA].pPort;
+
+ _RS_MASK = g_APinDescription[RS].ulPin;
+ _CS_MASK = g_APinDescription[CS].ulPin;
+ _SCLK_MASK = g_APinDescription[SCLK].ulPin;
+ _SDATA_MASK = g_APinDescription[SDATA].ulPin;
+ }
+#endif
+ }
+
+ _contrast = 126; //In otherwords, use default unless told otherwise
+
+ //_LCDwidth = 132;
+ //_LCDheight = 132;
+}
+
+void gLCD::setForeColour(DEFAULT_DATA_TYPE Red, DEFAULT_DATA_TYPE Green, DEFAULT_DATA_TYPE Blue){
+ _ForeRed = Red & 0x0F;
+ _ForeGreen = Green & 0x0F;
+ _ForeBlue = Blue & 0x0F;
+}
+
+void gLCD::setBackColour(DEFAULT_DATA_TYPE Red, DEFAULT_DATA_TYPE Green, DEFAULT_DATA_TYPE Blue){
+ _BackRed = Red & 0x0F;
+ _BackGreen = Green & 0x0F;
+ _BackBlue = Blue & 0x0F;
+}
+
+void gLCD::setForeColour(DEFAULT_WIDE_DATA_TYPE colour){
+ _ForeRed = (colour >> 16) & 0x0F;
+ _ForeGreen = (colour >> 8) & 0x0F;
+ _ForeBlue = colour & 0x0F;
+}
+
+void gLCD::setBackColour(DEFAULT_WIDE_DATA_TYPE colour){
+ _BackRed = (colour >> 16) & 0x0F;
+ _BackGreen = (colour >> 8) & 0x0F;
+ _BackBlue = colour & 0x0F;
+}
+
+//This one is inefficient and not used internally, but it is useful in certain situations
+void gLCD::twoPixels(DEFAULT_DATA_TYPE SendR1, DEFAULT_DATA_TYPE SendG1, DEFAULT_DATA_TYPE SendB1, DEFAULT_DATA_TYPE SendR2, DEFAULT_DATA_TYPE SendG2, DEFAULT_DATA_TYPE SendB2){
+ DEFAULT_DATA_TYPE SendR1G1,SendB1R2,SendG2B2,SendFourth;
+ if(_driver & 0x01){
+ SendR1G1 = SendR1;
+ SendB1R2 = (SendG1 << 4) | (SendB1 & 0x0F);
+ SendG2B2 = SendR2;
+ SendFourth = (SendG2 << 4) | (SendB2 & 0x0F);
+ twoPixels(SendR1G1, SendB1R2, SendG2B2, SendFourth);
+ } else {
+ //Note that SendFourth is unused for these, so to save time we don't bother giving it a value.
+ SendR1G1 = (SendR1 << 4) | (SendG1 & 0x0F);
+ SendB1R2 = (SendB1 << 4) | (SendR2 & 0x0F);
+ SendG2B2 = (SendG2 << 4) | (SendB2 & 0x0F);
+ twoPixels(SendR1G1, SendB1R2, SendG2B2);
+ }
+}
+
+//This one is not used internally, but it is useful in certain situations
+void gLCD::twoPixels(DEFAULT_DATA_TYPE SendR1G1, DEFAULT_DATA_TYPE SendB1R2, DEFAULT_DATA_TYPE SendG2B2){
+ //Add both pixels to the window
+ SendByte(_parameter, SendR1G1);
+ SendByte(_parameter, SendB1R2);
+ SendByte(_parameter, SendG2B2);
+}
+
+void gLCD::twoPixels(DEFAULT_DATA_TYPE SendR1G1, DEFAULT_DATA_TYPE SendB1R2, DEFAULT_DATA_TYPE SendG2B2, DEFAULT_DATA_TYPE SendFourth){
+ //Add both pixels to the window
+ SendByte(_parameter, SendR1G1);
+ SendByte(_parameter, SendB1R2);
+ SendByte(_parameter, SendG2B2);
+ SendByte(_parameter, SendFourth);
+}
+
+
+void gLCD::setSendColour16bit(DEFAULT_DATA_TYPE Colour){
+ //Get type for each pixel
+ DEFAULT_DATA_TYPE pixelOne = Colour & 1;
+ DEFAULT_DATA_TYPE pixelTwo = (Colour >> 1) & 1;
+
+ //For 16bit:
+ //Pixel data is in the format: RRRRRGGG GGGBBBBB RRRRRGGG GGGBBBBB, where this is two pixels worth of data
+
+ //Is pixel one foreground or background
+ if (pixelOne){
+ _SendRG = _ForeRed;
+ _SendBR = (_ForeGreen << 4) | (_ForeBlue);
+ } else {
+ _SendRG = _BackRed;
+ _SendBR = (_BackGreen << 4) | (_BackBlue);
+ }
+ //Is pixel two foreground or background
+ if (pixelTwo){
+ _SendGB = _ForeRed;
+ _SendFourth = (_ForeGreen << 4) | (_ForeBlue);
+ } else {
+ _SendGB = _BackRed;
+ _SendFourth = (_BackGreen << 4) | (_BackBlue);
+ }
+}
+
+void gLCD::setSendColour12bit(DEFAULT_DATA_TYPE Colour){
+ //Get type for each pixel
+ DEFAULT_DATA_TYPE pixelOne = Colour & 1;
+ DEFAULT_DATA_TYPE pixelTwo = (Colour >> 1) & 1;
+
+ //For 12 bit:
+ //Pixel data is in the format: RRRRGGGG BBBBRRRR GGGGBBBB, where this is two pixels worth of data
+
+ //Is pixel one foreground or background
+ if (pixelOne){
+ _SendRG = _ForeRed << 4;
+ _SendRG |= _ForeGreen;
+ _SendBR = _ForeBlue << 4;
+ } else {
+ _SendRG = _BackRed << 4;
+ _SendRG |= _BackGreen;
+ _SendBR = _BackBlue << 4;
+ }
+ //Is pixel two foreground or background
+ if (pixelTwo){
+ _SendBR |= _ForeRed;
+ _SendGB = _ForeGreen << 4;
+ _SendGB |= _ForeBlue;
+ } else {
+ _SendBR |= _BackRed;
+ _SendGB = _BackGreen << 4;
+ _SendGB |= _BackBlue;
+ }
+}
+
+void gLCD::twoPixels(DEFAULT_DATA_TYPE Colour){
+ (*this.*setSendColour)(Colour);
+ //Add both pixels to the window
+ (*this.*sendTwoPixels)();
+}
+
+void gLCD::two16bitPixels(){
+ //Add both pixels to the window (use the old colour data)
+ SendByte(_parameter, _SendRG);
+ SendByte(_parameter, _SendBR);
+ SendByte(_parameter, _SendGB);
+ SendByte(_parameter, _SendFourth);
+}
+
+void gLCD::two12bitPixels(){
+ SendByte(_parameter, _SendRG);
+ SendByte(_parameter, _SendBR);
+ SendByte(_parameter, _SendGB);
+}
+
+void gLCD::Window(){
+ Window(X1,X2,Y1,Y2); //Use the global coordinates to call the window
+}
+
+void gLCD::mapWindowCoordinates(DEFAULT_MID_SIGNED_DATA_TYPE &_X1, DEFAULT_MID_SIGNED_DATA_TYPE &_Y1, DEFAULT_MID_SIGNED_DATA_TYPE &_X2, DEFAULT_MID_SIGNED_DATA_TYPE &_Y2){
+ static DEFAULT_MID_SIGNED_DATA_TYPE maxX = 131 - _Xzero;
+ static DEFAULT_MID_SIGNED_DATA_TYPE maxY = 131 - _Yzero;
+ //Flip in X
+ if(_rotation & 1){
+ DEFAULT_MID_SIGNED_DATA_TYPE tempX = _X2;
+ _X2 = maxX-_X1;
+ _X1 = maxX-tempX;
+ } else {
+ _X1 += _Xzero;
+ _X2 += _Xzero;
+ }
+ //Flip in Y
+ if (_rotation & 2){
+ DEFAULT_MID_SIGNED_DATA_TYPE tempY = _Y2;
+ _Y2 = maxY-_Y1;
+ _Y1 = maxY-tempY;
+ } else {
+ _Y1 += _Yzero;
+ _Y2 += _Yzero;
+ }
+ //Flip in X=Y
+ if (_rotation & 4){
+ DEFAULT_MID_SIGNED_DATA_TYPE tempX;
+ tempX = _X1;
+ _X1 = _Y1;
+ _Y1 = tempX;
+ tempX = _X2;
+ _X2 = _Y2;
+ _Y2 = tempX;
+ }
+}
+
+void gLCD::Window(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ //_X1 = _X1 + _Xzero; //Apply offset to window
+ //_Y1 = _Y1 + _Yzero;
+ //_X2 = _X2 + _Xzero;
+ //_Y2 = _Y2 + _Yzero;
+ mapWindowCoordinates(_X1,_Y1,_X2,_Y2); //Apply window offset and rotate (if needed).
+ SendWindow(_X1,_Y1,_X2,_Y2); //send the window to the screen.
+}
+
+void gLCD::SendWindow(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ if (_Phillips){
+ SendByte(_command, 0x2A); //Column adress
+ SendByte(_parameter, _Y1); //y-Position upper left corner
+ SendByte(_parameter, _Y2); //y-Position of lower right corner
+ SendByte(_command, 0x2B); //Page adressing
+ SendByte(_parameter, _X1); //X-Position upper left corner
+ SendByte(_parameter, _X2); //x-Position of lower right corner
+ SendByte(_command, 0x2C); //RAMWR - Ram Write
+
+ } else {
+ SendByte(_command, 0x15); //Column adress
+ SendByte(_parameter, _X1); //X-Position upper left corner
+ SendByte(_parameter, _X2); //x-Position of lower right corner
+ SendByte(_command, 0x75); //Page adressing
+ SendByte(_parameter, _Y1); //y-Position upper left corner
+ SendByte(_parameter, _Y2); //y-Position of lower right corner
+ SendByte(_command, 0x5C); //RAMWR - Ram Write
+ }
+}
+
+
+void gLCD::SendByte(DataType Command, DEFAULT_DATA_TYPE data){
+
+ DEFAULT_DATA_TYPE i;
+ if (_fast){
+ setRS(); //Startup LCD Communication
+ clrCS(); //start of sequence
+
+ //Send Command or parameter
+ clrSCLK(); //Clock 0
+ if(Command){ //Send a bit
+ setSDATA();
+ } else {
+ clrSDATA();
+ }
+ setSCLK(); //Clock 1
+
+ //Send data
+ for (i = 0;i < 8; i++){
+ clrSCLK(); //Clock 0
+ if(data & 0x80){ //isolate and send a data bit
+ setSDATA();
+ } else {
+ clrSDATA();
+ }
+ data <<= 1; //shift the data up
+ setSCLK(); //Clock 1
+ }
+
+ setCS(); //end of sequence
+ } else {
+ digitalWrite(_RS, 1); //Startup LCD Communication
+ digitalWrite(_CS, 0); //start of sequence
+ //Send Command or parameter
+ digitalWrite(_SCLK, 0); //Clock 0
+ digitalWrite(_SDATA, Command); //Send a bit
+ digitalWrite(_SCLK, 1); //Clock 1
+
+ //Send data
+ /*DEFAULT_DATA_TYPE mask = 0x80;
+ for (i = 7;i >= 0; i--){
+ digitalWrite(_SCLK, 0); //Clock 0
+ digitalWrite(_SDATA, data & mask); //Send a bit
+ mask >>= 1;
+ digitalWrite(_SCLK, 1); //Clock 1
+ }*/
+ DEFAULT_DATA_TYPE mask = 0x80;
+ do {
+ digitalWrite(_SCLK, 0); //Clock 0
+ digitalWrite(_SDATA, data & mask); //Send a bit
+ mask >>= 1;
+ digitalWrite(_SCLK, 1); //Clock 1
+ } while (mask);
+ digitalWrite(_CS, 1); //end of sequence
+ }
+}
+
+void gLCD::Contrast(DEFAULT_SIGNED_DATA_TYPE contrast){
+ _contrast = contrast;
+ if (_Phillips){
+ if (_contrast > 63){
+ _contrast = 63;
+ }
+ if (_contrast < -63){
+ _contrast = -63;
+ }
+ SendByte(_command, 0x25); //Contrast Control
+ SendByte(_parameter, _contrast); //User defined contrast.
+ } else {
+ if (_contrast > 63){
+ _contrast = 63;
+ }
+ if (_contrast < 0){
+ _contrast = 0;
+ }
+ SendByte(_command, 0x81); //Contrast Control
+ SendByte(_parameter, _contrast); //User defined contrast.
+ SendByte(_parameter, 0x02); //Resistor Ratio - 0x02 should be fine for most screens
+ }
+}
+
+void gLCD::Configure(DEFAULT_DATA_TYPE normal){
+ if (_Phillips){
+ SendByte(_command, 0x36); //Configure Display
+ if(normal){
+ SendByte(_parameter, _normalScan); //RGB order, mirror display x or y.
+ } else {
+ SendByte(_parameter, _inverseScan);
+ }
+ } else {
+ SendByte(_command, 0xBC); //Display Control
+ if (normal){
+ SendByte(_parameter, _normalScan); //Scan direction
+ } else {
+ SendByte(_parameter, _inverseScan);
+ }
+ SendByte(_parameter, 0x00); //RGB colour order
+ SendByte(_parameter, 0x02); //colour mode - 4096 colours
+ }
+}
+
+void gLCD::setRotation(ImageRotation rotation){
+ _rotation = rotation;
+}
+ImageRotation gLCD::getRotation(){
+ return _rotation;
+}
+
+void gLCD::begin(DEFAULT_SIGNED_DATA_TYPE Xzero, DEFAULT_SIGNED_DATA_TYPE Yzero, DEFAULT_DATA_TYPE InvertColour, DriverType driver, ImageRotation rotation){
+ _driver = driver;
+ _rotation = rotation;
+ _Phillips = (_driver & 0x04) ? 0 : 1;
+ if(_Phillips){
+ sendTwoPixels = &gLCD::two12bitPixels;
+ setSendColour = &gLCD::setSendColour12bit;
+ } else {
+ if(_driver & 0x01) {
+ sendTwoPixels = &gLCD::two16bitPixels;
+ setSendColour = &gLCD::setSendColour16bit;
+ } else {
+ sendTwoPixels = &gLCD::two12bitPixels;
+ setSendColour = &gLCD::setSendColour12bit;
+ }
+ }
+ _Yzero = Yzero;
+ _Xzero = Xzero;
+
+ digitalWrite(_RS,0); //Reset LCD
+
+ delay(30);
+
+ //By using digitalWrite for these, the pins will be readied for using direct writes (especially important for Due)
+ digitalWrite(_CS,1); //Select LCD
+ digitalWrite(_SDATA,1); //Set Data Pin High
+ digitalWrite(_SCLK,1); //Set Clock Pin High
+ digitalWrite(_RS,1); //Startup LCD
+
+ delay(30); //Wait after Reset
+
+ if(_Phillips){
+ SendByte(_command, 0x11); //Wake up from sleep mode
+ } else {
+ SendByte(_command, 0xCA); //Configure Display
+ SendByte(_parameter, 0x00); //2 divisions, switching period=8 (default)
+ SendByte(_parameter, 0x20); //nlines/4 - 1 = 132/4 - 1 = 32)
+ SendByte(_parameter, 0x00); //no inversely highlighted lines
+
+ SendByte(_command, 0xBB); //Common Output Scan (avoid split display)...
+ SendByte(_parameter, 0x01); //...Scan 1->69, 69->132
+
+ SendByte(_command, 0xD1); //Enable Oscillators
+
+ SendByte(_command, 0x94); //Sleep Out
+
+ SendByte(_command, 0x20); //Voltage Regulators On
+ SendByte(_parameter, 0x0F); //Ref voltage, then circuit voltage, then booster
+ }
+ if (InvertColour){
+ SendByte(_command, _Phillips ? 0x20 : 0xA7); //Invert Display Colour
+ }
+
+ if(_Phillips){
+ SendByte(_command, 0x3A); //Colour Control
+ SendByte(_parameter, 0x03); //colour mode - 4096 colours
+
+ SendByte(_command, 0x36); //Configure Display
+ if (_driver & 1){ //When driver bit 1 is on, then the value of this parameter is ajusted so that x is mirrored from normal.
+ _normalScan = 0x60 - ((_driver & 2)<<4);
+ _inverseScan = 0xC0 + ((_driver & 2)<<4);
+ SendByte(_parameter, _normalScan); //RGB order, mirror display x or y. 0x60 = RGB, no mirroring
+ // 0x68 = BGR, no mirroring
+ // 0xA0 = RGB, mirror X and Y
+ // 0xA8 = BGR, mirror X and Y
+ } else {
+ _normalScan = 0x20 - ((_driver & 2)<<4);
+ _inverseScan = 0x80 + ((_driver & 2)<<4);
+ SendByte(_parameter, _normalScan); //RGB order, mirror display x or y. 0x20 = RGB, no mirroring
+ // 0x28 = BGR, no mirroring
+ // 0xE0 = RGB, mirror X and Y
+ // 0xE8 = BGR, mirror X and Y
+ }
+ SendByte(_command, 0x25); //Contrast Control
+ SendByte(_parameter, 0x30); //-63 to 63: sets contrast - 0x30 is default.
+ } else {
+ SendByte(_command, 0xBC); //Display Control
+ _normalScan = 0x04;
+ _inverseScan = 0x01;
+ SendByte(_parameter, _normalScan); //Scan direction (left-->right or right-->left)
+ SendByte(_parameter, 0x00); //RGB colour order
+ SendByte(_parameter, (_driver & 0x01) ? 0x04 : 0x02); //colour mode - 4096 colours (for some EPSON Screens 12bpp isn't supported, so we use 16, but scale up 12bits to fit)
+
+ SendByte(_command, 0x81); //Contrast Control
+ SendByte(_parameter, 0x2B); //0 to 63: sets contrast - 0x2B is default.
+ SendByte(_parameter, 0x02); //Resistor Ratio - 0x02 should be fine for most screens
+ }
+
+ delay(100); //Allow Power to stablise
+
+ SendByte(_command, _Phillips?0x29:0xAF); //Display On
+
+ delay(40);
+
+ setForeColour(0x0F,0x0F,0x0F); //Display is White foreground and Blue background
+ setBackColour(0x00,0x00,0x0F);
+
+ Clear();
+}
+
+void gLCD::displayOff(){
+ if(_Phillips){
+ //DISPOFF
+ SendByte(_command, 0x28);
+ } else {
+ //DISOFF
+ SendByte(_command, 0xAE);
+ }
+}
+
+void gLCD::displayOn(){
+ if(_Phillips){
+ //DISPON
+ SendByte(_command, 0x29);
+ } else {
+ //DISON
+ SendByte(_command, 0xAF);
+ }
+}
+
+void gLCD::Clear(){
+ //int i,j;
+
+ SendWindow(0,0,131,131); //Create a window the size of the screen
+ (*this.*setSendColour)(0);//All pixels are the same colour, so do the calculation only once
+ for (DEFAULT_MID_DATA_TYPE i = 0;i < 8712;i++){
+ (*this.*sendTwoPixels)(); //send the rest using the existing colours
+ }
+}
+
+#if ARDUINO >= 100
+size_t gLCD::write(const unsigned char character){
+ char temp[2] = {0};
+ temp[0] = character;
+ return write((const unsigned char *)temp,1);
+}
+#else
+void gLCD::write(const unsigned char character){
+ char temp[2] = {0};
+ temp[0] = character;
+ write(temp,1);
+}
+#endif
+
+#if ARDUINO >= 100
+size_t gLCD::write(const unsigned char *buffer, size_t size){
+#else
+void gLCD::write(const unsigned char *buffer, size_t size){
+#endif
+ size_t returnSize = size;
+ DEFAULT_SIGNED_DATA_TYPE j,k, xcnt, ycnt;
+
+ DEFAULT_DATA_TYPE wrapText = ((Font >> 3) & 1); //Whether to wrap the font.
+
+ DEFAULT_DATA_TYPE width = (Font & 1); //Double width (BOLD)
+ DEFAULT_DATA_TYPE height = ((Font >> 1) & 1); //Double height (Large text when used with fontwidth)
+ DEFAULT_DATA_TYPE background = ((Font >> 2) & 1); //Whether the text has a background
+
+ DEFAULT_MID_SIGNED_DATA_TYPE X = X1;
+ DEFAULT_MID_SIGNED_DATA_TYPE& _X1 = X1;
+ DEFAULT_MID_SIGNED_DATA_TYPE startX = X1;
+ DEFAULT_MID_SIGNED_DATA_TYPE Y = Y1;
+ DEFAULT_MID_SIGNED_DATA_TYPE& _Y1 = Y1;
+ DEFAULT_MID_SIGNED_DATA_TYPE startY = Y1;
+
+ char char2print;
+ DEFAULT_DATA_TYPE data;
+ DEFAULT_DATA_TYPE databit;
+ DEFAULT_SIGNED_DATA_TYPE max = 126 + numberOfCustomCharacters;
+ while (size--){ //Start at beginning of string and work along
+ //Finds the character to print, and adjusts it to a position in the ASCII array
+ char2print = *buffer++; //increment pointer for next time.
+ if (char2print == 13){
+ //Skip a carraige return
+ } if (char2print == 10){
+ //If it is a line feed, move to the next line.
+ _X1 = startX;
+ X = _X1;
+ startY += (8<<height);
+ _Y1 = startY;
+ Y = _Y1;
+ continue; //Move on to next character in string
+ } else if ((char2print < 32)&&(char2print > max)&&(max < 0)){ //The > max allows for the 'numberOfCustomCharacters' custom characters to be used
+ //If it is not a printable character, print a space instead.
+ char2print = 0;
+ } else if (((char2print < 32)||(char2print > max))&&(max > 0)){ //The > max allows for the 'numberOfCustomCharacters' custom characters to be used
+ //If it is not a printable character, print a space instead.
+ char2print = 0;
+ } else {
+ char2print -= 32;
+ }
+
+ DEFAULT_DATA_TYPE character = (DEFAULT_DATA_TYPE)char2print;
+
+ if(background && !_rotation){
+ //Print the character (more efficient, but only works with ImageRotation == 0
+ Window(_X1,_Y1,_X1+(6<<width)-1,_Y1+(8<<height)-1); //Create a window the size of one character, then fill it with the the character
+ for (xcnt = 0;xcnt < 5;xcnt++){
+ for (j = 0;j <= width;j++){
+ if (height){
+ //If double height, each pair of pixels will be the same, and there will be 8 pairs of them.
+ for (ycnt = 0;ycnt < 8;ycnt++){
+ #ifdef _LIB_SAM_
+ data = charData[character][xcnt];
+ #else
+ data = pgm_read_byte(&(charData[character][xcnt]));
+ #endif
+ databit = (data >> ycnt) & 1;
+ databit |= databit << 1;
+ twoPixels(databit);
+ }
+ } else {
+ //If not height, each pair of pixels will be two distinct pixels, so we need to set the colour for each correctly.
+ for (ycnt = 0;ycnt < 7;ycnt += 2){
+ #ifdef _LIB_SAM_
+ data = charData[character][xcnt];
+ #else
+ data = pgm_read_byte(&(charData[character][xcnt]));
+ #endif
+ databit = (data >> ycnt) & 3;
+ twoPixels(databit);
+ }
+ }
+ }
+ }
+ //Fill in the character seperator pixels
+ (*this.*setSendColour)(0);
+ for (j = 0;j < ((4<<height)<<width);j++){
+ (*this.*sendTwoPixels)();
+ }
+ } else {
+ if (background){
+ Window(_X1,_Y1,_X1+(6<<width)-1,_Y1+(8<<height)-1); //Create a window the size of one character, then fill it with the background colour
+ (*this.*setSendColour)(0);
+ for (xcnt = 0;xcnt < 6;xcnt++){
+ for (j = 0;j < ((4<<height)<<width);j++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ //Print the character
+ for (xcnt = 0;xcnt < 5;xcnt++){
+ //Do this once or twice depending on width format
+ for (j = 0;j <= width;j++){
+ for (ycnt = 0;ycnt <8;ycnt++){
+ #ifdef _LIB_SAM_
+ data = charData[character][xcnt];
+ #else
+ data = pgm_read_byte(&(charData[character][xcnt]));
+ #endif
+ databit = (data >> ycnt) & 1; //isolate the data bit
+
+ //Do this once or twice depending on height format
+ for (k = 0;k <= height;k++){
+ if(databit){
+ systemPlot(X,Y,3);
+ }
+ Y++;//increase Y offset
+ }
+ }
+ X++; //increase X offset
+ Y = _Y1; //Y back to zero offset
+ }
+ }
+ }
+ _X1 += (6<<width); // Move X position so that next character knows where to be placed
+ if (wrapText && (131 - _X1 < (6<<width)) && (size > 1)){
+ //If text wrap is enabled, and there is insufficient space to place the next character, continue on a new line
+ if(background){
+ Window(_X1,_Y1,131,_Y1+(8<<height)-1); //Create a window the height of one character and to the edge of the screen,
+ (*this.*setSendColour)(0); //then fill it with the background colour
+ for (xcnt = 0;xcnt <= 131 - _X1;xcnt++){
+ for (ycnt = 0;ycnt < (4<<height);ycnt++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ //Now move to the next line ready to print the next character
+ _X1 = startX;
+ X = _X1;
+ startY += (8<<height);
+ _Y1 = startY;
+ Y = _Y1;
+ if (Y > 128){
+#if ARDUINO >= 100
+ return (returnSize - size); //No point going any further, just drop the rest of the text and return the amount already printed.
+#else
+ return;
+#endif
+ }
+ }
+ X = _X1; //X back to zero offset
+ }
+#if ARDUINO >= 100
+ return returnSize;
+}
+#else
+}
+#endif
+
+void gLCD::systemPlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Colour){
+ //The systemPlot function does not set the global coordinate as it may be being used as a reference by an internal function.
+ Window(_X1,_Y1,_X1,_Y1); //Creates a window of 1 pixel
+ Colour |= Colour << 1;
+ twoPixels(Colour);
+}
+
+void gLCD::systemPlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1){
+ //The systemPlot function does not set the global coordinate as it may be being used as a reference by an internal function.
+ Window(_X1,_Y1,_X1,_Y1); //Creates a window of 1 pixel
+ (*this.*sendTwoPixels)();
+}
+
+void gLCD::Plot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Colour){
+ setCoordinate(_X1,_Y1);
+ systemPlot(X1,Y1,Colour); //Call the system plot function
+}
+
+void gLCD::Plot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1){
+ Plot(_X1,_Y1,format >> 2); //Use the format variable instead
+}
+
+void gLCD::Plot(DEFAULT_DATA_TYPE Colour){
+ systemPlot(X1,Y1,Colour);
+}
+
+void gLCD::Plot(){
+ Plot(format >> 2); //Use the format variable instead
+}
+
+void gLCD::setFormat(DEFAULT_DATA_TYPE _format){
+ format = _format;
+}
+
+void gLCD::setFont(DEFAULT_DATA_TYPE _Font) {
+ Font = _Font;
+}
+
+void gLCD::setCoordinate(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ setCoordinate(_X1,_Y1);
+ setCoordinate(_X2,_Y2,2);
+}
+
+void gLCD::setCoordinate(DEFAULT_MID_SIGNED_DATA_TYPE X, DEFAULT_MID_SIGNED_DATA_TYPE Y, DEFAULT_DATA_TYPE pair){
+ if(pair == 1){
+ X1 = X;
+ Y1 = Y;
+ } else {
+ X2 = X;
+ Y2 = Y;
+ }
+}
+
+void gLCD::Circle(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Radius){
+ setCoordinate(_X1,_Y1);
+ Circle(Radius);
+}
+
+void gLCD::Circle(DEFAULT_DATA_TYPE Radius, DEFAULT_DATA_TYPE _format){
+ setFormat(_format);
+ Circle(Radius);
+}
+
+void gLCD::Circle(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Radius, DEFAULT_DATA_TYPE _format){
+ setFormat(_format);
+ Circle(_X1,_Y1,Radius);
+}
+
+void gLCD::Circle(DEFAULT_DATA_TYPE Radius){
+ /*
+ Implimentation of Bresenham's Circle Algorithm
+ */
+ DEFAULT_DATA_TYPE fillColour = format & 1;
+ DEFAULT_DATA_TYPE nofill = (format >> 1) & 1;
+ DEFAULT_DATA_TYPE borderColour = (format >> 2) & 1;
+
+ fillColour |= fillColour << 1;
+ borderColour |= borderColour << 1;
+
+ DEFAULT_DATA_TYPE X = Radius;
+ DEFAULT_DATA_TYPE Y = 0;
+ DEFAULT_MID_SIGNED_DATA_TYPE error = 0;
+ DEFAULT_MID_SIGNED_DATA_TYPE dx = 1 - (Radius << 1);
+ DEFAULT_MID_SIGNED_DATA_TYPE dy = 1;
+
+ //Have to do it twice if it is filled in unfortunately
+
+ if (!nofill){
+ (*this.*setSendColour)(fillColour);
+ while (X >= Y){
+ CircleFill(X,Y,X1,Y1);
+ Y++;
+ error += dy;
+ dy += 2;
+ if ((dx + (error<<1)) > 0){
+ X--;
+ error += dx;
+ dx += 2;
+ }
+ }
+ }
+
+ X = Radius;
+ Y = 0;
+ error = 0;
+ dx = 1 - (Radius << 1);
+ dy = 1;
+ (*this.*setSendColour)(borderColour);
+ while (X >= Y){
+ CirclePlot(X,Y,X1,Y1);
+ Y++;
+ error += dy;
+ dy += 2;
+ if ((dx + (error<<1)) > 0){
+ X--;
+ error += dx;
+ dx += 2;
+ }
+ }
+}
+
+void gLCD::CircleFill(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+
+ DEFAULT_MID_SIGNED_DATA_TYPE i;
+ Window(_X2-_X1,_Y2+_Y1,_X2+_X1,_Y2+_Y1);
+ for(i = 0; i < _X1; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(_X2-_X1,_Y2-_Y1,_X2+_X1,_Y2-_Y1);
+ for(i = 0; i < _X1; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(_X2-_Y1,_Y2+_X1,_X2+_Y1,_Y2+_X1);
+ for(i = 0; i < _Y1; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(_X2-_Y1,_Y2-_X1,_X2+_Y1,_Y2-_X1);
+ for(i = 0; i < _Y1; i++){
+ (*this.*sendTwoPixels)();
+ }
+}
+
+void gLCD::CirclePlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ //Circle is Symmetrical, so we can plot the whole thing having only calculated an octant
+ systemPlot(_X2+_X1,_Y2+_Y1); //Octant 1
+ systemPlot(_X2-_X1,_Y2+_Y1); //Octant 4
+ systemPlot(_X2+_X1,_Y2-_Y1); //Octant 8
+ systemPlot(_X2-_X1,_Y2-_Y1); //Octant 5
+ systemPlot(_X2+_Y1,_Y2+_X1); //Octant 2
+ systemPlot(_X2-_Y1,_Y2+_X1); //Octant 3
+ systemPlot(_X2+_Y1,_Y2-_X1); //Octant 7
+ systemPlot(_X2-_Y1,_Y2-_X1); //Octant 6
+}
+
+void gLCD::Line(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2, DEFAULT_DATA_TYPE _format){
+ setCoordinate(_X1,_Y1,_X2,_Y2);
+ Line(_format);
+}
+
+void gLCD::Line(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ setCoordinate(_X1,_Y1,_X2,_Y2);
+ Line();
+}
+
+void gLCD::Line(DEFAULT_DATA_TYPE _format){
+ setFormat(_format);
+ Line();
+}
+
+void gLCD::Line(){
+ DEFAULT_MID_SIGNED_DATA_TYPE xdir = 1; //Amount by which X changes
+ DEFAULT_MID_SIGNED_DATA_TYPE ydir = 1; //Amount by which Y changes
+ DEFAULT_MID_SIGNED_DATA_TYPE error;
+ DEFAULT_MID_SIGNED_DATA_TYPE i;
+ DEFAULT_MID_SIGNED_DATA_TYPE X = X1;
+ DEFAULT_MID_SIGNED_DATA_TYPE Y = Y1;
+
+ DEFAULT_DATA_TYPE Colour = format >> 2;
+ Colour |= Colour << 1;
+ (*this.*setSendColour)(Colour);
+ /*
+ Implimentation of Bresenham's Line Algorithm
+ */
+
+ //The algorithm works for only one octant. By reversing the direction, the algorithm can work for 4 of the octants
+
+ DEFAULT_MID_SIGNED_DATA_TYPE dx = X2 - X; //Change in X
+ DEFAULT_MID_SIGNED_DATA_TYPE dy = Y2 - Y; //Change in Y
+
+ if (dx < 0){
+ xdir = -1;
+ dx = 0 - dx;
+ }
+ if (dy < 0){
+ ydir = -1;
+ dy = 0 - dy;
+ }
+
+ DEFAULT_MID_SIGNED_DATA_TYPE dy2 = dy << 1; //Change in Y with twice the precision
+ DEFAULT_MID_SIGNED_DATA_TYPE dx2 = dx << 1; //Change in X with twice the precision
+
+
+ //By choosing the major axis, one that experiances greatest change, the algorithm will work for all octants
+ if (dx > dy){
+ //The X axis see's the largest change, so with each new pixel, X always changes by 1
+ error = dy2 - dx;
+ for (i = 0; i <= dx; i++){
+ systemPlot(X,Y); //Print the pixel
+ X += xdir; //move to next x value
+ if (error > 0){
+ //Error is above the midpoint. So, we move up one
+ error += (dy2 - dx2);
+ Y += ydir;
+ } else {
+ //Error is below midpoint, so we keep the same y value
+ error += dy2;
+ }
+ }
+ } else {
+ //The Y axis see's the largest change, so with each new pixel, Y always changes by 1
+ error = dx2 - dy;
+ for (i = 0; i <= dy; i++){
+ systemPlot(X,Y); //Print the pixel
+ Y += ydir; //move to next y value
+ if (error > 0){
+ //Error is above the midpoint. So, we move right one
+ error += (dx2 - dy2);
+ X += xdir;
+ } else {
+ //Error is below midpoint, so we keep the same x value
+ error += dx2;
+ }
+ }
+ }
+}
+
+void gLCD::Box(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2, DEFAULT_DATA_TYPE _format){
+ setCoordinate(_X1,_Y1,_X2,_Y2);
+ Box(_format);
+}
+
+void gLCD::Box(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ setCoordinate(_X1,_Y1,_X2,_Y2);
+ Box();
+}
+
+void gLCD::Box(DEFAULT_DATA_TYPE _format){
+ setFormat(_format);
+ Box();
+}
+
+void gLCD::Box(){
+ DEFAULT_DATA_TYPE fillColour = format & 1;
+ DEFAULT_DATA_TYPE noFill = format & 2;
+ DEFAULT_DATA_TYPE borderColour = (format >> 2) & 1;
+
+ DEFAULT_MID_SIGNED_DATA_TYPE dx = (X2 - X1) >> 1;
+ DEFAULT_MID_SIGNED_DATA_TYPE dy = (Y2 - Y1) >> 1;
+
+ fillColour |= fillColour << 1;
+ borderColour |= borderColour << 1;
+
+ if(!noFill){
+ (*this.*setSendColour)(fillColour);
+ Window(X1,Y1,X2,Y2); //Create a window for the box
+ for (DEFAULT_MID_SIGNED_DATA_TYPE Y = Y1;Y <= Y2;Y++){
+ for (DEFAULT_MID_SIGNED_DATA_TYPE X = X1;X <= X2;X++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+
+ //draw border
+ (*this.*setSendColour)(borderColour);
+ Window(X1, Y1, X2, Y1);
+ for(DEFAULT_MID_SIGNED_DATA_TYPE i = 0; i <= dx; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(X2, Y1, X2, Y2);
+ for(DEFAULT_MID_SIGNED_DATA_TYPE i = 0; i <= dy; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(X1, Y2, X2, Y2);
+ for(DEFAULT_MID_SIGNED_DATA_TYPE i = 0; i <= dx; i++){
+ (*this.*sendTwoPixels)();
+ }
+ Window(X1, Y1, X1, Y2);
+ for(DEFAULT_MID_SIGNED_DATA_TYPE i = 0; i <= dy; i++){
+ (*this.*sendTwoPixels)();
+ }
+}
+
+void gLCD::RedGreen(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ DEFAULT_DATA_TYPE dy = (_Y2 - _Y1) >> 4; //Y2 - Y1 should be a multiple of eight when invoking this, otherwise it wont work
+ DEFAULT_DATA_TYPE dx = (_X2 - _X1) >> 5; //X2 - X1 should be a multiple of sixteen when invoking this, otherwise it wont work
+
+ Window(_X1,_Y1,_X2-1,_Y2-1);
+ for (DEFAULT_DATA_TYPE i = 0;i < 16;i++){
+ for (DEFAULT_DATA_TYPE k = 0;k < dy;k++){
+ for (DEFAULT_DATA_TYPE j = 0;j < 16;j++){
+ setForeColour(i,j,0);
+ (*this.*setSendColour)(3);
+ for (DEFAULT_DATA_TYPE l = 0;l < dx;l++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ }
+}
+
+void gLCD::GreenBlue(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ DEFAULT_DATA_TYPE dy = (_Y2 - _Y1) >> 4; //Y2 - Y1 should be a multiple of eight when invoking this, otherwise it wont work
+ DEFAULT_DATA_TYPE dx = (_X2 - _X1) >> 5; //X2 - X1 should be a multiple of sixteen when invoking this, otherwise it wont work
+
+ Window(_X1,_Y1,_X2-1,_Y2-1);
+ for (DEFAULT_DATA_TYPE i = 0;i < 16;i++){
+ for (DEFAULT_DATA_TYPE k = 0;k < dy;k++){
+ for (DEFAULT_DATA_TYPE j = 0;j < 16;j++){
+ setForeColour(0,i,j);
+ (*this.*setSendColour)(3);
+ for (DEFAULT_DATA_TYPE l = 0;l < dx;l++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ }
+}
+
+void gLCD::BlueRed(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+ DEFAULT_DATA_TYPE dy = (_Y2 - _Y1) >> 4; //Y2 - Y1 should be a multiple of eight when invoking this, otherwise it wont work
+ DEFAULT_DATA_TYPE dx = (_X2 - _X1) >> 5; //X2 - X1 should be a multiple of sixteen when invoking this, otherwise it wont work
+
+ Window(_X1,_Y1,_X2-1,_Y2-1);
+ for (DEFAULT_DATA_TYPE i = 0;i < 16;i++){
+ for (DEFAULT_DATA_TYPE k = 0;k < dy;k++){
+ for (DEFAULT_DATA_TYPE j = 0;j < 16;j++){
+ setForeColour(j,0,i);
+ (*this.*setSendColour)(3);
+ for (DEFAULT_DATA_TYPE l = 0;l < dx;l++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ }
+}
+
+void gLCD::ColourBars(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2){
+
+ DEFAULT_DATA_TYPE dy = _Y2 - _Y1;
+ DEFAULT_DATA_TYPE dx = (_X2 - _X1) >> 4;
+
+ DEFAULT_DATA_TYPE colour[6][3] = {
+ {15,0,0},
+ {15,15,0},
+ {0,15,0},
+ {0,15,15},
+ {0,0,15},
+ {15,0,15}
+ };
+
+ Window(_X1,_Y1,_X2-1,_Y2-1);
+ for (DEFAULT_DATA_TYPE i = 0;i < 6;i++){
+ setForeColour(colour[i][0],colour[i][1],colour[i][2]);
+ (*this.*setSendColour)(3);
+ for (DEFAULT_DATA_TYPE k = 0;k < dx;k++){
+ for (DEFAULT_DATA_TYPE j = 0;j < dy;j++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+ dx = dx << 2;
+ dy = dy >> 5;
+
+ for (DEFAULT_DATA_TYPE k = 0;k < dx;k++){
+ for (DEFAULT_DATA_TYPE j = 0;j < 16;j++){
+ setForeColour(j,j,j);
+ (*this.*setSendColour)(3);
+ for (DEFAULT_DATA_TYPE l = 0;l < dy;l++){
+ (*this.*sendTwoPixels)();
+ }
+ }
+ }
+}
+
+void gLCD::testPattern(){
+ setBackColour(15,15,15);
+ Clear();
+ RedGreen(1,1,65,65);
+ GreenBlue(1,65,65,129);
+ BlueRed(65,1,129,65);
+ ColourBars(65,65,129,129);
+}
View
513 Version 3_5/gLCD.h
@@ -0,0 +1,513 @@
+/*
+ Sparkfun Nokia knockoff screen 128x128 controller.
+
+ Written by Thomas Carpenter (2011->2012)
+
+ ==================================================================================================
+ Current Library Version: 3.5
+
+ Date | Version | Changes
+ -----------+---------+-----------------------------------------------------------------------------
+ 07/02/2013 | 3.5 | - Fixed printing of floating point values, and mult iple strings one after another.
+ | | The coordinate for printing was not being updated to represent the end of the string
+ | |
+ 13/01/2013 | 3.4 | - Fixed character wrapping when screen is rotated.
+ | |
+ | | - Added operator for ImageRotation to allow it to be incremented/decremented.
+ | |
+ 13/01/2013 | 3.3b | - Bug-fix for rotation. Cures obscure offsets when screen is rotated, and fixes clear() function.
+ 10/01/2013 | 3.3 | - Added the ability to rotate the screen by 90, 180 or 270 degrees if the display is upside down.
+ | |
+ | | - Corrected bug in version 3.2 whereby AVR datatypes for coordinates were CHAR not INT, meaning screens with
+ | | offsets couldn't address last pixels (e.g. 127+3=-125 rather than 130 which resulted in error in pixel address)
+ | |
+ | | - Improved efficiency of write() function (replaced multiply-by-2 with bitshift)
+ | |
+ 31/12/2012 | 3.2b | - digitalWrite() is very slow on Due, so added 'High Speed' mode on the Due to improve performance dramatically.
+ 22/10/2012 | 3.2 | - Updated the library to include support for the Arduino Due. Note however there is no 'High Speed'
+ | | mode on the Due, it uses digitalWrite() in either mode. This is not an issue as the due is very fast.
+ | |
+ | | - Added a simple character wrap feature which if selected as part of the font will begin continue printing
+ | | on subsequent lines if the text is too long to fit on the screen.
+ | |
+ 06/10/2012 | 3.1 | - Added another driver type (EPSON_5). This is for screens that dont support the 3pixel/2DEFAULT_DATA_TYPE mode.
+ | | For these a 4pixel/2DEFAULT_DATA_TYPE mode is used. In order to not have constant checks for which type of data
+ | | mode is being used, there are seperate functions for each, the correct function is set via a function
+ | | pointer. This change is internal, so should not affect existing code.
+ | | Speed should also not be affected, however this has cost 0.5kB to 1kB of program space.
+ | |
+ | | - definitions for fonts and formats have been added to improve readability of user code.
+ | |
+ 18/09/2012 | 3.0 | - The library has been converted to use the Arduino Print class allowing more familiar
+ | | calls such as print() and println() to be used, rather than the original Print(String,x,y,font).
+ | | The original function now gives an error message explaining the changes.
+ | |
+ | | - There are now global X1, Y1, X2 and Y2 variables, along with a global Font and Format. This
+ | | allows consecutive calls to the display functions without having to repeatedly specify these
+ | | variables.
+ | |
+ | | - Fixed the printing function so that the '\n' character moves to a new line on the screen.
+ | |
+ | | - Change the Init() function to be named begin() to more closely match the arduino style. The
+ | | function is also now more common between the two displays (no extra variables), making it
+ | | easier to follow.
+ | |
+ |---------|
+ | |
+ 17/07/2012 | 2.5 | - Added the ability to have many custom characters.
+ | |
+ 01/06/2012 | 2.4 | - Constructor method [gLCD(,,,)] uses built in port decoding from Arduino.h which means
+ | | that the correct port is automatically determined, and #defines have thus been removed.
+ | | This also improves compatibility with other boards including Teensy and Pro.
+ | |
+ 18/01/2012 | 2.3 | - Update Phillips Init() call to also work with screens that would scan
+ | | top to bottom before, and thus display fonts wrong (thanks github member: mumps)
+ | |
+ 05/01/2012 | 2.2 | - Corrected printing of Wide fonts (thanks Sparkfun Member #8577)
+ | |
+ 22/12/2011 | 2.1 | - updated twoPixels() to take 6 values (R1,G1,B1,R2,G2,B2) as well as still being able
+ | | to take the 3 it did before (R1G1,B1R2,G2B2)
+ | |
+ 03/12/2011 | 2.0 | - Contrast function can now be called at any point in the program (as long as it is
+ | | AFTER the init() call). This means that the contrast can now be changed as many
+ | | times as you like during the program, without the need to reinitialise the screen.
+ | |
+ | | - Library now supports Ardiuno 1.0
+ | |
+ |---------|
+ | |
+ 06/11/2011 | 1.4 | - Corrected the drawing of borders when the Box function is called, where before
+ | | it used to get the length of the x and y axis lines switched
+ | | - Added two new functions: displayOff(), which turns the display off to save power,
+ | | and displayOn(), which turns it back on again.
+ | |
+ 22/10/2011 | 1.3 | - Added ability to invert phillips display
+ | |
+ 14/10/2011 | 1.2 | - Written a faster digital write set of functions. This speeds up the display by a factor of 10
+ | |
+ 09/10/2011 | 1.1 | - Character data array is now stored in PROGMEM to free up 480DEFAULT_DATA_TYPEs of SRAM
+ | 1.0 | - Major rewrite of printing to screen which has massively increased performance.
+ | |
+ | | - Circles are now filled MUCH faster.
+ | | - Test pattern renders even faster.
+ | | - More control over colour of circles and boxes.
+ | |
+ |---------|
+ | |
+ 08/10/2011 | 0.8 | - Fixed Issue with Window() macro and the Epson controller - First pixel was drawn in wrong place.
+ | | This required changing the scan direction of the Epson screen, and of the Phillips screen so that
+ | | both render the same image in the same orientation.
+ | | - testPattern() now more efficient and renders much faster.
+ | 0.7 | - Contrast depends heavily on the type of screen, so new function to set contrast has been added.
+ | | - Added support for Phillips displays, and displays whose colour is inverted (i.e White = Black)
+ | 0.6 | - Fixed Lines not drawing correctly if Y1 > Y2
+ | 0.5 | - Added Examples to show how to use functions
+ | | - Added Circle drawing algorithm
+ | | - Can now select colour of the Line() and Plot() as foreground or background colour
+ | 0.4 | - Added co-ordinate offset. (On some displays, (0,0) is not visible)
+ | | Window() function has had the offset built in, as all functions use
+ | | it to draw anything on the screen.
+ | | Offset is specified when calling Init();
+ | |
+ 07/10/2011 | 0.3 | - Added testPattern Function.
+ | 0.2 | - Fixed functions not working correctly if X or Y were greater than 126.
+ | | - Increased speed of software SPI
+ | | - Added Version history
+ | | - Simplified Box formatting
+ | |
+ 06/10/2011 | 0.1 | - Initial library created with some basic functions
+ | |
+
+ ===================================================================================================
+
+ Wishlist/To Do:
+ - Detect which controller the screen has
+
+ - Draw Triangles (Filled and Unfilled)
+
+ ===================================================================================================
+
+ Functions:
+ gLCD(RS,CS,SCLK,SDATA)
+ gLCD(RS,CS,SCLK,SDATA,speed) - Connect screen pins. Reset, !Chip Select, Clock, and Data. Speed is optional and may be omitted
+ If speed is given (and is 1), then the FAST digital write will be used.
+
+ begin(Xzero, Yzero, InvertColour, EPSON) - Initialise the display. This may need changing for certain screens.
+ Xzero and Yzero are (0,0) offset. Invert colour can be used if White
+ appears as black, which it does on some displays.(1 = Invert, 0 = Normal)
+ EPSON specifies that an Epson display is being used
+
+ begin(Xzero, Yzero, InvertColour, PHILLIPS_x) - the last DEFAULT_DATA_TYPE controls how the phillips display will behave, and requires
+ some trial and error to get right.
+ First, try setting it to PHILLIPS_0 and observe which way the screen prints
+ the image onto the screen.
+ -If it builds up the image from the LEFT(connector end is the top):
+ PHILLIPS_0 is correct.
+ -If it builds up from the RIGTH:
+ set it to PHILLIPS_1 (it should now scan from the LEFT)
+ -If it builds up from the BOTTOM:
+ set it to PHILLIPS_2 (it should now scan from the LEFT, else try PHILLIPS_3)
+ -If it builds up from the TOP:
+ set it to PHILLIPS_3 (it should now scan from the LEFT, else try PHILLIPS_2)
+ begin(Xzero, Yzero, InvertColour, DRIVER(see above), ROTATION_x) - rotate the display by either 0, 90, 180, or 270 degrees ANTICLOCWISE.
+
+ displayOff() - Turns the display off.
+ displayOn() - Turns it back on again.
+
+ testPattern() - Prints a colour table to check that all colours working properly.
+
+ Contrast(contrast) - 'contrast' is a value between 0 and 63 (EPSON) or -63 and 63 (Phillips).
+ If the Screen is too dark, or you cant see anything send a value >0x2B (<0x00 for Phillips). If you cant see all
+ the different colours distinctly on the test pattern, send a value <0x2B (<0x30 (but >0x00) for Phillips). The default values
+ should work for many screens, so you may not have to use this at all.
+
+ Contrast() should be called BEFORE Init(). It is only needed if the display doesn't look right with just Init() alone.
+
+ NOTE: after Init() has been called, Contrast will do nothing.
+
+
+ Plot(X,Y,Colour) - Places a dot on the screen at (X,Y). If colour = 3, then it is in ForeColour. If colour = 0, then in BackColour
+
+ Line(X1,Y1,X2,Y2,Colour) - Draws a line between (X1,Y1) and (X2,Y2) inclusive, in forground colour (Colour = 1) or background colour (Colour = 0)
+
+ Box(X1,Y1,X2,Y2,format) - Draws a box from (X1,Y1) to (X2,Y2) inclusive.
+ format controls how the box will look (b7..b3 are ignored)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 1 | x | Draws a box with just a border of colour BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 1 | x | Draws a box with just a border of colour ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 0 | Draws a box with border in BackColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 0 | Draws a box with border in ForeColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 1 | Draws a box with border in BackColour and fill inside it with ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 1 | Draws a box with border in ForeColour and fill inside it with ForeColour
+
+ Circle(X1,Y1,Radius,format) - Draws a Circle from (X1,Y1) with radius 'Radius'.
+ format controls how the box will look (b7..b3 are ignored)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 1 | x | Draws a circle with just a border of colour BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 1 | x | Draws a circle with just a border of colour ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 0 | Draws a circle with border in BackColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 0 | Draws a circle with border in ForeColour and fill inside it with BackColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 0 | 0 | 1 | Draws a circle with border in BackColour and fill inside it with ForeColour
+ ----+----+----+-----------------------------------------------------------------------------
+ 1 | 0 | 1 | Draws a circle with border in ForeColour and fill inside it with ForeColour
+
+ setFont(Font) - Sets the global font. Font is DEFAULT_DATA_TYPE with each bit having a meaning.
+ These are as follows (b7..b3 are ignored)
+
+ b2 | b1 | b0 | Meaning
+ ----+----+----+---------------------------------------
+ 0 | x | x | Text has transparent background
+ ----+----+----+---------------------------------------
+ 1 | x | x | Text has solid background
+ ----+----+----+---------------------------------------
+ x | 0 | 0 | Text normal. (6 x 8 pixels)
+ ----+----+----+---------------------------------------
+ x | 0 | 1 | Text Wide. (12 x 8 pixels)
+ ----+----+----+---------------------------------------
+ x | 1 | 0 | Text Tall. (6 x 16 pixels)
+ ----+----+----+---------------------------------------
+ x | 1 | 1 | Text Tall and Wide. (12 x 16 pixels)
+
+ Clear() - Blanks everything on display. All pixels go to background colour
+
+ setBackColour(R,G,B) - Sets the global RGB background colour. Doesn't affect anything already onscreen. R, G and B are 4bit long
+
+ setForeColour(R,G,B) - Sets the global RGB foreground colour. Doesn't affect anything already onscreen. R, G and B are 4bit long
+*/
+
+#ifndef gLCD_h
+#define gLCD_h
+ #if ARDUINO >= 100
+ #include "Arduino.h"
+ #else
+ #include "WProgram.h"
+ #endif
+
+ #ifdef _LIB_SAM_
+ #define DEFAULT_DATA_TYPE unsigned int
+ #define DEFAULT_MID_DATA_TYPE unsigned int
+ #define DEFAULT_WIDE_DATA_TYPE unsigned int
+ #define DEFAULT_SIGNED_DATA_TYPE signed int
+ #define DEFAULT_MID_SIGNED_DATA_TYPE signed int
+ #define DEFAULT_WIDE_SIGNED_DATA_TYPE signed int
+
+ #define setRS() _RS_PORT->PIO_SODR = _RS_MASK
+ #define clrRS() _RS_PORT->PIO_CODR = _RS_MASK
+ #define setCS() _CS_PORT->PIO_SODR = _CS_MASK
+ #define clrCS() _CS_PORT->PIO_CODR = _CS_MASK
+ #define setSCLK() _SCLK_PORT->PIO_SODR = _SCLK_MASK
+ #define clrSCLK() _SCLK_PORT->PIO_CODR = _SCLK_MASK
+ #define setSDATA() _SDATA_PORT->PIO_SODR = _SDATA_MASK
+ #define clrSDATA() _SDATA_PORT->PIO_CODR = _SDATA_MASK
+ #else
+ #define DEFAULT_DATA_TYPE unsigned char
+ #define DEFAULT_MID_DATA_TYPE unsigned int
+ #define DEFAULT_WIDE_DATA_TYPE unsigned long
+ #define DEFAULT_SIGNED_DATA_TYPE signed char
+ #define DEFAULT_MID_SIGNED_DATA_TYPE signed int
+ #define DEFAULT_WIDE_SIGNED_DATA_TYPE signed long
+
+ #define setRS() *_RS_PORT |= _RS_HIGH
+ #define clrRS() *_RS_PORT &= _RS_LOW
+ #define setCS() *_CS_PORT |= _CS_HIGH
+ #define clrCS() *_CS_PORT &= _CS_LOW
+ #define setSCLK() *_SCLK_PORT |= _SCLK_HIGH
+ #define clrSCLK() *_SCLK_PORT &= _SCLK_LOW
+ #define setSDATA() *_SDATA_PORT |= _SDATA_HIGH
+ #define clrSDATA() *_SDATA_PORT &= _SDATA_LOW
+ #endif
+
+ #define GLCD_WHITE 0x0F0F0F
+ #define GLCD_BLACK 0x000000
+ #define GLCD_GREEN 0x000F00
+ #define GLCD_LIME 0x080F00
+ #define GLCD_BLUE 0x00000F
+ #define GLCD_RED 0x0F0000
+ #define GLCD_GREY 0x080808
+ #define GLCD_ORANGE 0x0F0800
+ #define GLCD_CYAN 0x000F0F
+ #define GLCD_YELLOW 0x0F0F00
+ #define GLCD_LEMON 0x0F0F08
+ #define GLCD_MAGENTA 0x0F000F
+ #define GLCD_PINK 0x0F0808
+
+ typedef enum{
+ EPSON_5 = 5,
+ EPSON_4 = 4,
+ EPSON = 4,
+ PHILLIPS_3 = 3,
+ PHILLIPS_2 = 2,
+ PHILLIPS_1 = 1,
+ PHILLIPS_0 = 0
+ } DriverType;
+
+ typedef enum{
+ HIGH_SPEED = true,
+ NORMAL_SPEED = false
+ } SpeedMode;
+
+ typedef enum{
+ _parameter = 1,
+ _command = 0
+ } DataType;
+
+ typedef enum {
+ ROTATION_0 = 0,//0b000,
+ ROTATION_180 = 3,//0b011,
+ ROTATION_90 = 5,//0b101,
+ ROTATION_270 = 6//0b110
+ } ImageRotation;
+
+ inline ImageRotation& operator++(ImageRotation& rotation);
+ inline ImageRotation& operator--(ImageRotation& rotation);
+ inline ImageRotation operator++(ImageRotation& rotation, int){
+ ImageRotation tmp(rotation);
+ ++rotation;
+ return tmp;
+ }
+ inline ImageRotation operator--(ImageRotation& rotation, int){
+ ImageRotation tmp(rotation);
+ --rotation;
+ return tmp;
+ }
+ inline ImageRotation& operator++(ImageRotation& rotation){
+ switch(rotation){
+ case ROTATION_0: rotation=ROTATION_90; break;
+ case ROTATION_90: rotation=ROTATION_180; break;
+ case ROTATION_180: rotation=ROTATION_270; break;
+ case ROTATION_270: rotation=ROTATION_0; break;
+ }
+ return rotation;
+ }
+ inline ImageRotation& operator--(ImageRotation& rotation){
+ switch(rotation){
+ case ROTATION_0: rotation=ROTATION_270; break;
+ case ROTATION_90: rotation=ROTATION_0; break;
+ case ROTATION_180: rotation=ROTATION_90; break;
+ case ROTATION_270: rotation=ROTATION_180; break;
+ }
+ return rotation;
+ }
+
+ #define Normal_SolidBG_Wrap 0b1100
+ #define Wide_SolidBG_Wrap 0b1101
+ #define Tall_SolidBG_Wrap 0b1110
+ #define Large_SolidBG_Wrap 0b1111
+ #define Normal_ClearBG_Wrap 0b1000
+ #define Wide_ClearBG_Wrap 0b1001
+ #define Tall_ClearBG_Wrap 0b1010
+ #define Large_ClearBG_Wrap 0b1011
+ #define Normal_SolidBG 0b100
+ #define Wide_SolidBG 0b101
+ #define Tall_SolidBG 0b110
+ #define Large_SolidBG 0b111
+ #define Normal_ClearBG 0b000
+ #define Wide_ClearBG 0b001
+ #define Tall_ClearBG 0b010
+ #define Large_ClearBG 0b011
+
+ #define Wrap_Text 1
+
+ #define OutlineBackColour 0b010
+ #define OutlineForeColour 0b110
+ #define SolidBackColour 0b000
+ #define BorderForeColour_FillBackColour 0b100
+ #define BorderBackColour_FillForeColour 0b001
+ #define SolidForeColour 0b101
+
+ class gLCD; //make function pointers valid.
+ typedef void (gLCD::*TwoPixelsMode)();
+ typedef void (gLCD::*SetSendColourMode)(DEFAULT_DATA_TYPE);
+
+ class gLCD : public Print{
+ private:
+ SetSendColourMode setSendColour; //Function pointer to select which setSendColour is used
+ TwoPixelsMode sendTwoPixels; //Function pointer to select which twoPixels is used
+ public:
+ gLCD(DEFAULT_DATA_TYPE RS, DEFAULT_DATA_TYPE CS, DEFAULT_DATA_TYPE SCLK, DEFAULT_DATA_TYPE SDATA, SpeedMode speed = NORMAL_SPEED); //Constructor. 'speed' can be omitted in call.
+ //function declarations
+ #if ARDUINO >= 100
+ virtual size_t write(const unsigned char *buffer, size_t size);//
+ virtual size_t write(const unsigned char character);//
+ using Print::write; // pull in write(str) from Print
+ #else
+ virtual void write(const unsigned char *buffer, size_t size);//
+ virtual void write(const unsigned char character);//
+ using Print::write; // pull in write(str) from Print
+ #endif
+ void begin(DEFAULT_SIGNED_DATA_TYPE Xzero, DEFAULT_SIGNED_DATA_TYPE Yzero, DEFAULT_DATA_TYPE InvertColour, DriverType driver, ImageRotation rotation = ROTATION_0);//
+ void Contrast(DEFAULT_SIGNED_DATA_TYPE contrast);//
+ void setForeColour(DEFAULT_DATA_TYPE Red, DEFAULT_DATA_TYPE Green, DEFAULT_DATA_TYPE Blue);//
+ void setForeColour(DEFAULT_WIDE_DATA_TYPE colour);
+ void setBackColour(DEFAULT_DATA_TYPE Red, DEFAULT_DATA_TYPE Green, DEFAULT_DATA_TYPE Blue);//
+ void setBackColour(DEFAULT_WIDE_DATA_TYPE colour);
+ void Clear();//
+ void setFont(DEFAULT_DATA_TYPE _Font);//
+ void setFormat(DEFAULT_DATA_TYPE _format);
+ //void setFormat(DEFAULT_DATA_TYPE _format);//
+ void setCoordinate(DEFAULT_MID_SIGNED_DATA_TYPE X, DEFAULT_MID_SIGNED_DATA_TYPE Y, DEFAULT_DATA_TYPE pair = 1); //setCoordinate(X1,Y1), setCoordinate(X1,Y1,1), setCoordinate(X2,Y2,2)
+ void setCoordinate(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);//
+ void Plot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Colour);//
+ void Plot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1);//
+ void Plot(DEFAULT_DATA_TYPE Colour);//
+ void Plot();//
+ void Line(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2, DEFAULT_DATA_TYPE _format);//
+ void Line(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);//
+ void Line(DEFAULT_DATA_TYPE _format);//
+ void Line();//
+ void Box(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2, DEFAULT_DATA_TYPE _format);//
+ void Box(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);//
+ void Box(DEFAULT_DATA_TYPE _format);//
+ void Box();//
+ void Circle(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Radius, DEFAULT_DATA_TYPE _format);//
+ void Circle(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Radius);//
+ void Circle(DEFAULT_DATA_TYPE Radius, DEFAULT_DATA_TYPE _format);//
+ void Circle(DEFAULT_DATA_TYPE Radius);//
+ void displayOn();//
+ void displayOff();//
+ void testPattern();//
+ void setRotation(ImageRotation rotation);
+ ImageRotation getRotation();
+
+ //This allows direct window writes, for example bitmap creation
+ void twoPixels(DEFAULT_DATA_TYPE SendR1G1, DEFAULT_DATA_TYPE SendB1R2, DEFAULT_DATA_TYPE SendG2B2, DEFAULT_DATA_TYPE SendFourth); //Forth DEFAULT_DATA_TYPE is only relevant for _EPSON_16bit
+ void twoPixels(DEFAULT_DATA_TYPE SendR1G1, DEFAULT_DATA_TYPE SendB1R2, DEFAULT_DATA_TYPE SendG2B2);
+ void twoPixels(DEFAULT_DATA_TYPE SendR1, DEFAULT_DATA_TYPE SendG1, DEFAULT_DATA_TYPE SendB1, DEFAULT_DATA_TYPE SendR2, DEFAULT_DATA_TYPE SendG2, DEFAULT_DATA_TYPE SendB2);//
+ void Window(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);//
+ void Window();//
+ void Configure(DEFAULT_DATA_TYPE normal); //1 = Normal, 0 = Bitmap (BMP files work best with this, though still a little buggy)
+ private:
+ void mapWindowCoordinates(DEFAULT_MID_SIGNED_DATA_TYPE &_X1, DEFAULT_MID_SIGNED_DATA_TYPE &_Y1, DEFAULT_MID_SIGNED_DATA_TYPE &_X2, DEFAULT_MID_SIGNED_DATA_TYPE &_Y2);//
+ void SendWindow(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);//
+ void SendByte(DataType Command, DEFAULT_DATA_TYPE data);
+ void setSendColour16bit(DEFAULT_DATA_TYPE Colour);
+ void setSendColour12bit(DEFAULT_DATA_TYPE Colour);
+ void two16bitPixels();
+ void two12bitPixels();
+ void twoPixels(DEFAULT_DATA_TYPE Colour);
+ void RedGreen(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void GreenBlue(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void BlueRed(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void ColourBars(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void CirclePlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void CircleFill(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_MID_SIGNED_DATA_TYPE _X2, DEFAULT_MID_SIGNED_DATA_TYPE _Y2);
+ void systemPlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1, DEFAULT_DATA_TYPE Colour);//
+ void systemPlot(DEFAULT_MID_SIGNED_DATA_TYPE _X1, DEFAULT_MID_SIGNED_DATA_TYPE _Y1);
+
+ //Variables
+ DEFAULT_DATA_TYPE _RS;
+ DEFAULT_DATA_TYPE _CS;
+ DEFAULT_DATA_TYPE _SCLK;
+ DEFAULT_DATA_TYPE _SDATA;
+#ifndef _LIB_SAM_
+ volatile DEFAULT_DATA_TYPE* _RS_PORT;
+ volatile DEFAULT_DATA_TYPE* _CS_PORT;
+ volatile DEFAULT_DATA_TYPE* _SCLK_PORT;
+ volatile DEFAULT_DATA_TYPE* _SDATA_PORT;
+ DEFAULT_DATA_TYPE _RS_HIGH;
+ DEFAULT_DATA_TYPE _CS_HIGH;
+ DEFAULT_DATA_TYPE _SCLK_HIGH;
+ DEFAULT_DATA_TYPE _SDATA_HIGH;
+ DEFAULT_DATA_TYPE _RS_LOW;
+ DEFAULT_DATA_TYPE _CS_LOW;
+ DEFAULT_DATA_TYPE _SCLK_LOW;
+ DEFAULT_DATA_TYPE _SDATA_LOW;
+#else
+ Pio* _RS_PORT;
+ Pio* _CS_PORT;
+ Pio* _SCLK_PORT;
+ Pio* _SDATA_PORT;
+ DEFAULT_DATA_TYPE _SDATA_MASK;
+ DEFAULT_DATA_TYPE _SCLK_MASK;
+ DEFAULT_DATA_TYPE _CS_MASK;
+ DEFAULT_DATA_TYPE _RS_MASK;
+#endif
+ boolean _fast;
+ DEFAULT_DATA_TYPE _normalScan;
+ DEFAULT_DATA_TYPE _inverseScan;
+
+ DEFAULT_DATA_TYPE _SendRG;
+ DEFAULT_DATA_TYPE _SendBR;
+ DEFAULT_DATA_TYPE _SendGB;
+ DEFAULT_DATA_TYPE _SendFourth; //This is used by EPSON_5 as they have a wierd 16bit colour arrangement.
+
+ DEFAULT_DATA_TYPE _ForeRed;
+ DEFAULT_DATA_TYPE _ForeGreen;
+ DEFAULT_DATA_TYPE _ForeBlue;
+ DEFAULT_DATA_TYPE _BackRed;
+ DEFAULT_DATA_TYPE _BackGreen;
+ DEFAULT_DATA_TYPE _BackBlue;
+
+ DEFAULT_SIGNED_DATA_TYPE _Yzero;
+ DEFAULT_SIGNED_DATA_TYPE _Xzero;
+ DEFAULT_DATA_TYPE _Ymax;
+ DEFAULT_DATA_TYPE _Xmax;
+ ImageRotation _rotation;
+
+ DEFAULT_DATA_TYPE Font;
+ DEFAULT_DATA_TYPE format;
+ DEFAULT_MID_SIGNED_DATA_TYPE X1;
+ DEFAULT_MID_SIGNED_DATA_TYPE Y1;
+ DEFAULT_MID_SIGNED_DATA_TYPE X2;
+ DEFAULT_MID_SIGNED_DATA_TYPE Y2;
+
+ DEFAULT_SIGNED_DATA_TYPE _contrast;
+ public:
+ DEFAULT_DATA_TYPE _Phillips;
+ DriverType _driver;
+ };
+
+#endif
View
72 Version 3_5/keywords.txt
@@ -0,0 +1,72 @@
+gLCD KEYWORD1
+ImageRotation KEYWORD1
+SpeedMode KEYWORD1
+DriverType KEYWORD1
+setForeColour KEYWORD2
+setBackColour KEYWORD2
+setCoordinate KEYWORD2
+setFont KEYWORD2
+setFormat KEYWORD2
+setRotation KEYWORD2
+getRotation KEYWORD2
+Clear KEYWORD2
+Plot KEYWORD2
+Line KEYWORD2
+Box KEYWORD2
+Circle KEYWORD2
+Init KEYWORD2
+displayOn KEYWORD2
+displayOff KEYWORD2
+testPattern KEYWORD2
+Contrast KEYWORD2
+Window KEYWORD2
+twoPixels KEYWORD2
+Configure KEYWORD2
+GLCD_WHITE LITERAL1
+GLCD_BLACK LITERAL1
+GLCD_LIME LITERAL1
+GLCD_GREEN LITERAL1
+GLCD_BLUE LITERAL1
+GLCD_RED LITERAL1
+GLCD_GREY LITERAL1
+GLCD_ORANGE LITERAL1
+GLCD_CYAN LITERAL1
+GLCD_LEMON LITERAL1
+GLCD_YELLOW LITERAL1
+GLCD_MAGENTA LITERAL1
+GLCD_PINK LITERAL1
+EPSON_5 LITERAL1
+EPSON_4 LITERAL1
+EPSON LITERAL1
+PHILLIPS_3 LITERAL1
+PHILLIPS_2 LITERAL1
+PHILLIPS_1 LITERAL1
+PHILLIPS_0 LITERAL1
+ROTATION_0 LITERAL1
+ROTATION_180 LITERAL1
+ROTATION_90 LITERAL1
+ROTATION_270 LITERAL1
+HIGH_SPEED LITERAL1
+NORMAL_SPEED LITERAL1
+Normal_SolidBG_Wrap LITERAL1
+Wide_SolidBG_Wrap LITERAL1
+Tall_SolidBG_Wrap LITERAL1
+Large_SolidBG_Wrap LITERAL1
+Normal_ClearBG_Wrap LITERAL1
+Wide_ClearBG_Wrap LITERAL1
+Tall_ClearBG_Wrap LITERAL1
+Large_ClearBG_Wrap LITERAL1
+Normal_SolidBG LITERAL1
+Wide_SolidBG LITERAL1
+Tall_SolidBG LITERAL1
+Large_SolidBG LITERAL1
+Normal_ClearBG LITERAL1
+Wide_ClearBG LITERAL1
+Tall_ClearBG LITERAL1
+Large_ClearBG LITERAL1
+OutlineBackColour LITERAL1
+OutlineForeColour LITERAL1
+SolidBackColour LITERAL1
+BorderForeColour_FillBackColour LITERAL1
+BorderBackColour_FillForeColour LITERAL1
+SolidForeColour LITERAL1
View
233 Version History.txt
@@ -1,119 +1,122 @@
- Sparkfun Nokia knockoff screen 128x128 controller.
- Written by Thomas Carpenter (2011->2012)
-
- ==================================================================================================
- Current Library Version: 3.3
-
- Date | Version | Changes
- -----------+---------+-----------------------------------------------------------------------------
- 13/01/2013 | 3.4 | - Fixed character wrapping when screen is rotated.
- | |
- | | - Added operator for ImageRotation to allow it to be incremented/decremented.
- | |
- 13/01/2013 | 3.3b | - Bug-fix for rotation. Cures obscure offsets when screen is rotated, and fixes clear() function.
- 10/01/2013 | 3.3 | - Added the ability to rotate the screen by 90, 180 or 270 degrees if the display is upside down.
- | |
- | | - Corrected bug in version 3.2 whereby AVR datatypes for coordinates were CHAR not INT, meaning screens with
- | | offsets couldn't address last pixels (e.g. 127+3=-125 rather than 130 which resulted in error in pixel address)
- | |
- | | - Improved efficiency of write() function (replaced multiply-by-2 with bitshift)
- | |
- 31/12/2012 | 3.2b | - digitalWrite() is very slow on Due, so added 'High Speed' mode on the Due to improve performance dramatically.
- | |
- 22/10/2012 | 3.2 | - Updated the library to include support for the Arduino Due. Note however there is no 'High Speed'
- | | mode on the Due, it uses digitalWrite() in either mode. This is not an issue as the due is very fast.
- | |
- | | - Added a simple character wrap feature which if selected as part of the font will begin continue printing
- | | on subsequent lines if the text is too long to fit on the screen.
- | |
- 06/10/2012 | 3.1 | - Added another driver type (EPSON_5). This is for screens that dont support the 3pixel/2DEFAULT_DATA_TYPE mode.
- | | For these a 4pixel/2DEFAULT_DATA_TYPE mode is used. In order to not have constant checks for which type of data
- | | mode is being used, there are seperate functions for each, the correct function is set via a function
- | | pointer. This change is internal, so should not affect existing code.
- | | Speed should also not be affected, however this has cost 0.5kB to 1kB of program space.
- | |
- | | - definitions for fonts and formats have been added to improve readability of user code.
- | |
- 18/09/2012 | 3.0 | - The library has been converted to use the Arduino Print class allowing more familiar
- | | calls such as print() and println() to be used, rather than the original Print(String,x,y,font).
- | | The original function now gives an error message explaining the changes.
- | |
- | | - There are now global X1, Y1, X2 and Y2 variables, along with a global Font and Format. This
- | | allows consecutive calls to the display functions without having to repeatedly specify these
- | | variables.
- | |
- | | - Fixed the printing function so that the '\n' character moves to a new line on the screen.
- | |
- | | - Change the Init() function to be named begin() to more closely match the arduino style. The
- | | function is also now more common between the two displays (no extra variables), making it
- | | easier to follow.
- | |
- |---------|
- | |
- 17/07/2012 | 2.5 | - Added the ability to have many custom characters.
- | |
- 01/06/2012 | 2.4 | - Constructor method [gLCD(,,,)] uses built in port decoding from Arduino.h which means
- | | that the correct port is automatically determined, and #defines have thus been removed.
- | | This also improves compatibility with other boards including Teensy and Pro.
- | |
- 18/01/2012 | 2.3 | - Update Phillips Init() call to also work with screens that would scan
- | | top to bottom before, and thus display fonts wrong (thanks github member: mumps)
- | |
- 05/01/2012 | 2.2 | - Corrected printing of Wide fonts (thanks Sparkfun Member #8577)
- | |
- 22/12/2011 | 2.1 | - updated twoPixels() to take 6 values (R1,G1,B1,R2,G2,B2) as well as still being able
- | | to take the 3 it did before (R1G1,B1R2,G2B2)
- | |
- 03/12/2011 | 2.0 | - Contrast function can now be called at any point in the program (as long as it is
- | | AFTER the init() call). This means that the contrast can now be changed as many
- | | times as you like during the program, without the need to reinitialise the screen.
- | |
- | | - Library now supports Ardiuno 1.0
- | |
- |---------|
- | |
- 06/11/2011 | 1.4 | - Corrected the drawing of borders when the Box function is called, where before
- | | it used to get the length of the x and y axis lines switched
- | | - Added two new functions: displayOff(), which turns the display off to save power,
- | | and displayOn(), which turns it back on again.
- | |
- 22/10/2011 | 1.3 | - Added ability to invert phillips display
- | |
- 14/10/2011 | 1.2 | - Written a faster digital write set of functions. This speeds up the display by a factor of 10
- | |
- 09/10/2011 | 1.1 | - Character data array is now stored in PROGMEM to free up 480DEFAULT_DATA_TYPEs of SRAM
- | 1.0 | - Major rewrite of printing to screen which has massively increased performance.
- | |
- | | - Circles are now filled MUCH faster.
- | | - Test pattern renders even faster.
- | | - More control over colour of circles and boxes.
- | |
- |---------|
- | |
- 08/10/2011 | 0.8 | - Fixed Issue with Window() macro and the Epson controller - First pixel was drawn in wrong place.
- | | This required changing the scan direction of the Epson screen, and of the Phillips screen so that
- | | both render the same image in the same orientation.
- | | - testPattern() now more efficient and renders much faster.
- | 0.7 | - Contrast depends heavily on the type of screen, so new function to set contrast has been added.
- | | - Added support for Phillips displays, and displays whose colour is inverted (i.e White = Black)
- | 0.6 | - Fixed Lines not drawing correctly if Y1 > Y2
- | 0.5 | - Added Examples to show how to use functions
- | | - Added Circle drawing algorithm