Permalink
Browse files

Philips color swap now in init function

There's an instruction in the Philips driver to swap RGB/BGR (MADCTL).
Awesome. Now, instead of calling swapColors for every setPixel we can
set it up in the display's initialization.

This swap can be set with a new (optional) parameter in init function,
but should default to the correct value.

Other changes:
* Better looking init function. Now only runs instructions specific to
driver type.
* Modified how contrast was set for Philips/Epson.
* Defaulting all example code to PHILIPS, this looks to be the most
common display now.
* Minor fixes in ChronoLCD code.
  • Loading branch information...
1 parent 296850a commit b2e487a29fbc8d5af9ef7728940b3592f98f3042 Jim Lindblom committed Jan 17, 2013
View
@@ -96,70 +96,80 @@ void LCDShield::LCDData(unsigned char data)
LCD_PORT_CS |= (1<<CS); // disable
}
-void LCDShield::init(int type)
+void LCDShield::init(int type, bool colorSwap)
{
driver = type;
+
+ // Initialize the control pins, and reset display:
+ cbi(LCD_PORT_SCK, SCK_PIN); // CLK = LOW
+ cbi(LCD_PORT_DIO, DIO); // DIO = LOW
+ delayMicroseconds(10); // 10us delay
+ sbi(LCD_PORT_CS, CS); // CS = HIGH
+ delayMicroseconds(10); // 10uS Delay
+ cbi(LCD_PORT_RES, LCD_RES); // RESET = LOW
+ delay(200); // 200ms delay
+ sbi(LCD_PORT_RES, LCD_RES); // RESET = HIGH
+ delay(200); // 200ms delay
+ sbi(LCD_PORT_SCK, SCK_PIN); // SCK_PIN = HIGH
+ sbi(LCD_PORT_DIO, DIO); // DIO = HIGH
+ delayMicroseconds(10); // 10us delay
+
+ if (driver == EPSON)
+ {
+ LCDCommand(DISCTL); // Display control (0xCA)
+ LCDData(0x0C); // 12 = 1100 - CL dividing ratio [don't divide] switching period 8H (default)
+ LCDData(0x20); // nlines/4 - 1 = 132/4 - 1 = 32 duty
+ LCDData(0x00); // No inversely highlighted lines
+
+ LCDCommand(COMSCN); // common scanning direction (0xBB)
+ LCDData(0x01); // 1->68, 132<-69 scan direction
+
+ LCDCommand(OSCON); // internal oscialltor ON (0xD1)
+ LCDCommand(SLPOUT); // sleep out (0x94)
+
+ LCDCommand(PWRCTR); // power ctrl (0x20)
+ LCDData(0x0F); // everything on, no external reference resistors
+
+ LCDCommand(DISINV); // invert display mode (0xA7)
+
+ LCDCommand(DATCTL); // data control (0xBC)
+ LCDData(0x03); // Inverse page address, reverse rotation column address, column scan-direction !!! try 0x01
+ LCDData(0x00); // normal RGB arrangement
+ LCDData(0x02); // 16-bit Grayscale Type A (12-bit color)
+
+ LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness (0x81)
+ LCDData(32); // volume (contrast) setting - fine tuning, original (0-63)
+ LCDData(3); // internal resistor ratio - coarse adjustment (0-7)
+
+ LCDCommand(NOP); // nop (0x25)
- delay(200);
-
- cbi(LCD_PORT_SCK, SCK_PIN); //CLK = LOW
- cbi(LCD_PORT_DIO, DIO); //DIO = LOW
- delayMicroseconds(10);
- sbi(LCD_PORT_CS, CS); //CS = HIGH
- delayMicroseconds(10);
- cbi(LCD_PORT_RES, LCD_RES); //RESET = LOW
- delay(200);
- sbi(LCD_PORT_RES, LCD_RES); //RESET = HIGH
- delay(200);
- sbi(LCD_PORT_SCK, SCK_PIN); // SCK_PIN = HIGH
- sbi(LCD_PORT_DIO, DIO); // DIO = HIGH
- delayMicroseconds(10);
-
- LCDCommand(DISCTL); // display control(EPSON)
- LCDData(0x0C); // 12 = 1100 - CL dividing ratio [don't divide] switching period 8H (default)
- LCDData(0x20);
- LCDData(0x00);
- LCDData(0x01);
-
- LCDCommand(COMSCN); // common scanning direction(EPSON)
- LCDData(0x01);
-
- LCDCommand(OSCON); // internal oscialltor ON(EPSON)
-
- LCDCommand(SLPOUT); // sleep out(EPSON)
- LCDCommand(SLEEPOUT); //sleep out(PHILLIPS)
-
- LCDCommand(PWRCTR); // power ctrl(EPSON)
- LCDData(0x0F); //everything on, no external reference resistors
- LCDCommand(BSTRON); //Booset On(PHILLIPS)
-
- LCDCommand(DISINV); // invert display mode(EPSON)
-
- LCDCommand(DATCTL); // data control(EPSON)
- LCDData(0x03); // correct for normal sin7
- LCDData(0x00); // normal RGB arrangement
- LCDData(0x02); // 16-bit Grayscale Type A
-
- LCDCommand(COLMOD); // Set Color Mode(PHILLIPS)
- LCDData(0x03);
-
- LCDCommand(MADCTL); // Memory Access Control(PHILLIPS)
- LCDData(0xC8);
-
-
- LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON)
- LCDData(0x24); // volume (contrast) setting - fine tuning, original
- LCDData(0x03); // internal resistor ratio - coarse adjustment
- LCDCommand(SETCON); // Set Contrast(PHILLIPS)
- LCDData(0x30);
-
- LCDCommand(NOP); // nop(EPSON)
- LCDCommand(NOPP); // nop(PHILLIPS)
-
- delayMicroseconds(200);
+ delay(100);
- LCDCommand(DISON); // display on(EPSON)
- LCDCommand(DISPON); // display on(PHILLIPS)
+ LCDCommand(DISON); // display on (0xAF)
+ }
+ else if (driver == PHILIPS)
+ {
+ LCDCommand(SLEEPOUT); // Sleep Out (0x11)
+ LCDCommand(BSTRON); // Booster voltage on (0x03)
+ LCDCommand(DISPON); // Display on (0x29)
+
+ //LCDCommand(INVON); // Inversion on (0x20)
+
+ // 12-bit color pixel format:
+ LCDCommand(COLMOD); // Color interface format (0x3A)
+ LCDData(0x03); // 0b011 is 12-bit/pixel mode
+
+ LCDCommand(MADCTL); // Memory Access Control(PHILLIPS)
+ if (colorSwap)
+ LCDData(0x08);
+ else
+ LCDData(0x00);
+
+ LCDCommand(SETCON); // Set Contrast(PHILLIPS)
+ LCDData(0x30);
+
+ LCDCommand(NOPP); // nop(PHILLIPS)
+ }
}
void LCDShield::clear(int color)
@@ -202,13 +212,19 @@ void LCDShield::clear(int color)
void LCDShield::contrast(char setting)
{
- if(driver)
- LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON)
- else
- LCDCommand(SETCON); // this is the contrast (PHILLIPS)
- LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24
-
- LCDCommand(NOP); // nop(EPSON)
+ if (driver == EPSON)
+ {
+ setting &= 0x3F; // 2 msb's not used, mask out
+ LCDCommand(VOLCTR); // electronic volume, this is the contrast/brightness(EPSON)
+ LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24
+ LCDData(3); // TODO: Make this coarse adjustment variable, 3's a good place to stay
+ }
+ else if (driver == PHILIPS)
+ {
+ setting &= 0x7F; // msb is not used, mask it out
+ LCDCommand(SETCON); // contrast command (PHILLIPS)
+ LCDData(setting); // volume (contrast) setting - course adjustment, -- original was 24
+ }
}
// Added by Steve Sparks @ Big Nerd Ranch.
@@ -222,7 +238,7 @@ void LCDShield::setPixel(int color, unsigned char x, unsigned char y)
y = (COL_HEIGHT - 1) - y;
x = (ROW_LENGTH - 1) - x;
- if (driver) // if it's an epson
+ if (driver == EPSON) // if it's an epson
{
LCDCommand(PASET); // page start/end ram
LCDData(x);
@@ -237,9 +253,8 @@ void LCDShield::setPixel(int color, unsigned char x, unsigned char y)
LCDData(((color&0x0F)<<4)|(color>>8));
LCDData(color&0x0FF);
}
- else // otherwise it's a phillips
+ else if (driver == PHILIPS) // otherwise it's a phillips
{
- color = swapColors(color);
LCDCommand(PASETP); // page start/end ram
LCDData(x);
LCDData(x);
View
@@ -356,7 +356,7 @@ class LCDShield
public:
LCDShield();
- void init(int type);
+ void init(int type, bool colorSwap = 0);
void clear(int color);
void contrast(char setting);
@@ -30,11 +30,11 @@
#define SECONDS 00
#define AMPM 0 // enter 0 for AM, 1 for PM
-#define CLOCK_RADIUS 50 // radius of clock face
-#define CLOCK_CENTER 55 // If you adjust the radius, you'll probably want to adjust this
-#define H_LENGTH 30 // length of hour hand
-#define M_LENGTH 40 // length of minute hand
-#define S_LENGTH 48 // length of second hand
+#define CLOCK_RADIUS 45 // radius of clock face
+#define CLOCK_CENTER 50 // If you adjust the radius, you'll probably want to adjust this
+#define H_LENGTH 25 // length of hour hand
+#define M_LENGTH 35 // length of minute hand
+#define S_LENGTH 43 // length of second hand
#define BACKGROUND BLACK // room for growth, adjust the background color according to daylight
#define C_COLOR RED // This is the color of the clock face, and digital clock
@@ -62,8 +62,8 @@ void setup()
ampm = AMPM;
/* Initialize the LCD, set the contrast, clear the screen */
- lcd.init(EPSON);
- lcd.contrast(40);
+ lcd.init(PHILIPS);
+ lcd.contrast(-63);
lcd.clear(BACKGROUND);
drawClock(); // Draw the clock face, this includes 12, 3, 6, 9
@@ -165,44 +165,19 @@ void setTime()
*/
void displayDigitalTime(int h, int m, int s, int ap)
{
- char timeChar[13] = {'x', 'x', 0x0A, 'x', 'x', 0x0A, 'x', 'x', ' ', ' '};
+ char timeChar[12];
- /* Gotta turn the values into individual integers */
- timeChar[0] = h/10;
- timeChar[1] = h - (timeChar[0] * 10);
- timeChar[3] = m/10;
- timeChar[4] = m - (timeChar[3] * 10);
- timeChar[6] = s/10;
- timeChar[7] = s - (timeChar[6] * 10);
-
- /* once we have each integer separated, we need to turn them
- into displayable characters. Adding 0x30 does this (check an
- ASCII table. We set the colons to 0x0A initially, this will
- turn them into the proper 0x3A.*/
- for (int i=0; i<8; i++)
- timeChar[i] += 0x30;
-
- timeChar[8] = ' '; // add a space between the time and AM/PM
-
- /* Add AM or PM to the end of the timeChar string */
if (!ap)
{
- timeChar[9] = 'A';
- timeChar[10] = 'M';
+ sprintf(timeChar, "%.2d:%.2d:%.2d AM", h, m, s);
}
else
{
- timeChar[9] = 'P';
- timeChar[10] = 'M';
+ sprintf(timeChar, "%.2d:%.2d:%.2d PM", h, m, s);
}
-
- /* add some blank spaces after the time, otherwise it'll display
- unwanted characters */
- timeChar[11] = ' ';
- timeChar[12] = ' ';
-
/* Print the time on the clock */
- lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22, C_COLOR, BACKGROUND);
+ lcd.setStr(timeChar, CLOCK_CENTER + CLOCK_RADIUS + 4, 22,
+ C_COLOR, BACKGROUND);
}
/*
@@ -269,4 +244,4 @@ void displayAnalogTime(int h, int m, int s)
hx = H_LENGTH * sin(3.14 * ((double) h)/180); // woo trig!
hy = H_LENGTH * cos(3.14 * ((double) h)/180); // woo trig!
lcd.setLine(CLOCK_CENTER, 66, CLOCK_CENTER+hx, 66+hy, H_COLOR); // print hour hand
-}
+}
@@ -19,17 +19,21 @@
LCDShield lcd;
int buttons[3] = {3, 4, 5}; // S1 = 3, S2 = 4, S3 = 5
-byte cont = 40; // Good center value for contrast
+signed char cont = -51; // Philips medium contrast
+//signed char cont = 40; // Epson medium contrast
void setup()
{
+ Serial.begin(9600);
for (int i=0; i<3; i++)
{
pinMode(buttons[i], INPUT); // Set buttons as inputs
digitalWrite(buttons[i], HIGH); // Activate internal pull-up
}
- lcd.init(EPSON); // Initialize the LCD, try using PHILLIPS if it's not working
+ // Initialize the LCD, try using EPSON if it's not working
+ lcd.init(PHILIPS);
+ // lcd.init(PHILIPS, 1); // Philips init with colors swapped. (Try this if red makes blue, etc).
lcd.contrast(cont); // Initialize contrast
lcd.clear(WHITE); // Set background to white
lcd.printLogo(); // Print SparkFun test logo
@@ -43,20 +47,21 @@ void loop()
if (!digitalRead(buttons[0])) // If S1 is hit, increase contrast
{
cont++;
- if (cont >= 60)
- cont = 0;
+ if (cont > 63) // Philips contrast goes from 63 to -64
+ cont = -64;
}
else if (!digitalRead(buttons[1])) // If s2 is hit, decrease contrast
{
cont--;
- if (cont >= 60)
- cont = 59;
+ if (cont < -64)
+ cont = 63;
}
else if (!digitalRead(buttons[2])) // If S3 is hit, reset contrast
{
- cont = 38;
+ cont = 0;
}
lcd.contrast(cont); // give LCD contrast command
+ Serial.println(cont);
delay(100); // Delay to give each button press a little more meaning
}
@@ -71,4 +76,4 @@ void testPattern()
lcd.setRect(80, 83, 131, 99, 1, RED);
lcd.setRect(80, 99, 131, 115, 1, BLUE);
lcd.setRect(80, 115, 131, 131, 1, BLACK);
-}
+}
@@ -25,8 +25,8 @@ LCDShield lcd;
void setup()
{
- lcd.init(EPSON); // This should only be init(EPSON) or init(PHILLIPS)
- lcd.contrast(44); // Feel free to change this for visibility, values between 0 and 60
+ lcd.init(PHILIPS); // Try EPSON if this doesn't work. If colors are swapped try init(PHILIPS, 1)
+ lcd.contrast(-51); // Feel free to change this for visibility, values between 0 and 60
lcd.clear(BACKGROUND);
// Initilize all circles' center points
@@ -84,4 +84,4 @@ void loop()
lcd.setPixel(BACKGROUND, xCir[i], yCir[i]); // clear center of circle
}
}
-}
+}

0 comments on commit b2e487a

Please sign in to comment.