summaryrefslogtreecommitdiff
path: root/obdlogger/LCD4Bit_mod.cpp
diff options
context:
space:
mode:
authorStanley Huang <stanleyhuangyc@gmail.com>2013-03-25 00:57:28 +0800
committerStanley Huang <stanleyhuangyc@gmail.com>2013-03-25 00:57:28 +0800
commit8e57c683d3d16f1dee320f10c411602ea38ba651 (patch)
tree75df3040d13c3f1850d93e29eb93a3836cae133c /obdlogger/LCD4Bit_mod.cpp
download2021-arduino-obd-8e57c683d3d16f1dee320f10c411602ea38ba651.tar.gz
2021-arduino-obd-8e57c683d3d16f1dee320f10c411602ea38ba651.tar.bz2
2021-arduino-obd-8e57c683d3d16f1dee320f10c411602ea38ba651.zip
initial commit
Diffstat (limited to 'obdlogger/LCD4Bit_mod.cpp')
-rw-r--r--obdlogger/LCD4Bit_mod.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/obdlogger/LCD4Bit_mod.cpp b/obdlogger/LCD4Bit_mod.cpp
new file mode 100644
index 0000000..c100c19
--- /dev/null
+++ b/obdlogger/LCD4Bit_mod.cpp
@@ -0,0 +1,209 @@
+/*
+LCD4Bit v0.1 16/Oct/2006 neillzero http://abstractplain.net
+
+What is this?
+An arduino library for comms with HD44780-compatible LCD, in 4-bit mode (saves pins)
+
+Sources:
+- The original "LiquidCrystal" 8-bit library and tutorial
+ http://www.arduino.cc/en/uploads/Tutorial/LiquidCrystal.zip
+ http://www.arduino.cc/en/Tutorial/LCDLibrary
+- DEM 16216 datasheet http://www.maplin.co.uk/Media/PDFs/N27AZ.pdf
+- Massimo's suggested 4-bit code (I took initialization from here) http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1144924220/8
+See also:
+- glasspusher's code (probably more correct): http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1160586800/0#0
+
+Tested only with a DEM 16216 (maplin "N27AZ" - http://www.maplin.co.uk/Search.aspx?criteria=N27AZ)
+If you use this successfully, consider feeding back to the arduino wiki with a note of which LCD it worked on.
+
+Usage:
+see the examples folder of this library distribution.
+
+*/
+
+#if defined(ARDUINO) && ARDUINO >= 100
+#include "Arduino.h"
+#else
+#include "WProgram.h"
+#endif
+
+#include "LCD4Bit_mod.h"
+
+//command bytes for LCD
+#define CMD_CLR 0x01
+#define CMD_RIGHT 0x1C
+#define CMD_LEFT 0x18
+#define CMD_HOME 0x02
+
+//pulse the Enable pin high (for a microsecond).
+//This clocks whatever command or data is in DB4~7 into the LCD controller.
+void LCD4Bit_mod::pulseEnablePin(){
+ digitalWrite(Enable,LOW);
+ delayMicroseconds(1);
+ // send a pulse to enable
+ digitalWrite(Enable,HIGH);
+ delayMicroseconds(1);
+ digitalWrite(Enable,LOW);
+ delay(1); // pause 1 ms. TODO: what delay, if any, is necessary here?
+}
+
+//push a nibble of data through the the LCD's DB4~7 pins, clocking with the Enable pin.
+//We don't care what RS and RW are, here.
+void LCD4Bit_mod::pushNibble(byte value)
+{
+ byte val_nibble= value & 0x0F; //clean the value. (unnecessary)
+
+ for (byte i=DB[0]; i <= DB[3]; i++) {
+ digitalWrite(i,val_nibble & 01);
+ val_nibble >>= 1;
+ }
+ pulseEnablePin();
+}
+
+//push a byte of data through the LCD's DB4~7 pins, in two steps, clocking each with the enable pin.
+void LCD4Bit_mod::pushByte(byte value)
+{
+ byte val_lower = value & 0x0F;
+ byte val_upper = value >> 4;
+ pushNibble(val_upper);
+ pushNibble(val_lower);
+}
+
+void LCD4Bit_mod::commandWriteNibble(byte nibble)
+{
+ digitalWrite(RS, LOW);
+ if (USING_RW) { digitalWrite(RW, LOW); }
+ pushNibble(nibble);
+}
+
+
+void LCD4Bit_mod::commandWrite(byte value)
+{
+ digitalWrite(RS, LOW);
+ if (USING_RW) { digitalWrite(RW, LOW); }
+ pushByte(value);
+ //TODO: perhaps better to add a delay after EVERY command, here. many need a delay, apparently.
+}
+
+
+
+
+//print the given character at the current cursor position. overwrites, doesn't insert.
+void LCD4Bit_mod::write(byte c)
+{
+ //set the RS and RW pins to show we're writing data
+ digitalWrite(RS, HIGH);
+ if (USING_RW) { digitalWrite(RW, LOW); }
+
+ //let pushByte worry about the intricacies of Enable, nibble order.
+ pushByte(c);
+}
+
+
+//print the given string to the LCD at the current cursor position. overwrites, doesn't insert.
+//While I don't understand why this was named printIn (PRINT IN?) in the original LiquidCrystal library, I've preserved it here to maintain the interchangeability of the two libraries.
+void LCD4Bit_mod::print(const char* msg)
+{
+ byte i; //fancy int. avoids compiler warning when comparing i with strlen()'s uint8_t
+ byte l = strlen(msg);
+ for (i=0; i < l; i++){
+ if (msg[i] >= 20) write(msg[i]);
+ }
+}
+
+
+//send the clear screen command to the LCD
+void LCD4Bit_mod::clear()
+{
+ commandWrite(CMD_CLR);
+ delay(1);
+}
+
+
+// initiatize lcd after a short pause
+//while there are hard-coded details here of lines, cursor and blink settings, you can override these original settings after calling .init()
+void LCD4Bit_mod::begin ()
+{
+ pinMode(Enable,OUTPUT);
+ pinMode(RS,OUTPUT);
+ if (USING_RW) { pinMode(RW,OUTPUT); }
+ pinMode(DB[0],OUTPUT);
+ pinMode(DB[1],OUTPUT);
+ pinMode(DB[2],OUTPUT);
+ pinMode(DB[3],OUTPUT);
+
+ delay(50);
+
+ //The first 4 nibbles and timings are not in my DEM16217 SYH datasheet, but apparently are HD44780 standard...
+ commandWriteNibble(0x03);
+ delay(5);
+ commandWriteNibble(0x03);
+ delayMicroseconds(100);
+ commandWriteNibble(0x03);
+ delay(5);
+
+ // needed by the LCDs controller
+ //this being 2 sets up 4-bit mode.
+ commandWriteNibble(0x02);
+ commandWriteNibble(0x02);
+ //todo: make configurable by the user of this library.
+ //NFXX where
+ //N = num lines (0=1 line or 1=2 lines).
+ //F= format (number of dots (0=5x7 or 1=5x10)).
+ //X=don't care
+
+ byte num_lines_ptn = (num_lines - 1) << 3;
+ byte dot_format_ptn = 0x00; //5x7 dots. 0x04 is 5x10
+
+ commandWriteNibble(num_lines_ptn | dot_format_ptn);
+ delayMicroseconds(60);
+
+ //The rest of the init is not specific to 4-bit mode.
+ //NOTE: we're writing full bytes now, not nibbles.
+
+ // display control:
+ // turn display on, cursor off, no blinking
+ commandWrite(0x0C);
+ delayMicroseconds(60);
+
+ //clear display
+ commandWrite(0x01);
+ delay(3);
+
+ // entry mode set: 06
+ // increment automatically, display shift, entire shift off
+ commandWrite(0x06);
+
+ delay(1);//TODO: remove unnecessary delays
+}
+
+
+//non-core stuff --------------------------------------
+//move the cursor to the given absolute position. line numbers start at 1.
+//if this is not a 2-line LCD4Bit_mod instance, will always position on first line.
+void LCD4Bit_mod::setCursor(byte x, byte line)
+{
+ //first, put cursor home
+ commandWrite(CMD_HOME);
+ //offset 40 chars in if second line requested
+ x += line * 40;
+
+ //advance the cursor to the right according to position. (second line starts at position 40).
+ for (byte i=0; i<x; i++) {
+ commandWrite(0x14);
+ }
+}
+
+//scroll whole display to left
+void LCD4Bit_mod::leftScroll(byte num_chars, unsigned int delay_time)
+{
+ for (byte i=0; i<num_chars; i++) {
+ commandWrite(CMD_LEFT);
+ delay(delay_time);
+ }
+}
+
+//Improvements ------------------------------------------------
+//Remove the unnecessary delays (e.g. from the end of pulseEnablePin()).
+//Allow the user to pass the pins to be used by the LCD in the constructor, and store them as member variables of the class instance.
+//-------------------------------------------------------------