4.3. library
/* NHD_i2c_lcd.cpp
* Library source for the NHD-0420D3Z-FL-GBW-V3
* Utilizes the Arduino Wire library
* Free to use and edit
* Most of the explanations are in the header file
*/
#include "NHD_i2c_lcd.h"
void NHD_i2c_lcd::init() {
Wire.begin();
Wire.setClock(CLK_FREQ);
delay(100);
clear();
setContrast(contrast);
backlightBrightness(brightness);
display(on);
setCursor(0, 0);
}
void NHD_i2c_lcd::underline(bool state) {
Wire.beginTransmission(LCD_ADDR);
if (state) {
Wire.write(PREFIX);
Wire.write(UNDERLINE_ON);
}
else {
Wire.write(PREFIX);
Wire.write(UNDERLINE_OFF);
}
Wire.endTransmission();
}
void NHD_i2c_lcd::display(bool state) {
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
if (state) {
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(DISP_ON);
}
else {
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(DISP_OFF);
}
delayMicroseconds(20);
Wire.endTransmission();
}
void NHD_i2c_lcd::blink(bool state) {
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
if (state) {
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(BLINK_ON);
}
else {
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(BLINK_OFF);
}
delayMicroseconds(20);
Wire.endTransmission();
}
void NHD_i2c_lcd::setCursor(byte x, byte y) {
byte pos = 0x00 + x;
cursorX = x;
cursorY = y;
switch (y) {
case 1:
pos += 0x40;
break;
case 2:
pos += 0x14;
break;
case 3:
pos += 0x54;
break;
default:
break;
}
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(SET_CURSOR);
delayMicroseconds(20);
Wire.write(pos);
delayMicroseconds(20);
Wire.endTransmission();
}
inline size_t NHD_i2c_lcd::write(uint8_t value) {
if (cursorX + 1 > 20) setCursor(0, cursorY + 1);
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(value);
delayMicroseconds(20);
Wire.endTransmission();
cursorX++;
}
void NHD_i2c_lcd::smartPrint(String msg) {
char chr;
uint8_t checkpoint = 0;
uint8_t nextlength = 0;
Wire.beginTransmission(LCD_ADDR);
for (int i = 0; i < min(msg.length(), 80); i++) {
if (i == checkpoint) {
nextlength = wordLength(&msg[i]);
checkpoint += nextlength + 1;
}
if (nextlength <= 20) {
if (cursorX + wordLength(&msg[i]) > 20) setCursor(0, cursorY + 1);
}
write(msg[i]);
}
Wire.endTransmission();
}
void NHD_i2c_lcd::printCustom(byte addr) {
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(addr);
delayMicroseconds(20);
Wire.endTransmission();
if (cursorX + 1 < 21) cursorX++;
}
void NHD_i2c_lcd::clearChars(byte x, byte y, byte number) {
setCursor(x, y);
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
for (byte i = 0; i < number; i++) {
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(BACKSPACE);
delayMicroseconds(20);
}
Wire.endTransmission();
delayMicroseconds(500);
}
void NHD_i2c_lcd::clear() {
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(CLEAR_SCREEN);
delayMicroseconds(20);
Wire.endTransmission();
delayMicroseconds(1200); // Minimum delay ~1140 us. If the delay is any less, any print immediately after clearing the screen might fail.
cursorX = 0;
cursorY = 0;
}
void NHD_i2c_lcd::setContrast(byte value) {
contrast = value;
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(SET_CONTRAST);
delayMicroseconds(20);
Wire.write(value);
delayMicroseconds(20);
Wire.endTransmission();
delayMicroseconds(1000);
}
void NHD_i2c_lcd::backlightBrightness(byte value) {
brightness = value;
Wire.beginTransmission(LCD_ADDR);
delayMicroseconds(20);
Wire.write(PREFIX);
delayMicroseconds(20);
Wire.write(BACKLIGHT_BRIGHTNESS);
delayMicroseconds(20);
Wire.write(value);
delayMicroseconds(20);
Wire.endTransmission();
delayMicroseconds(1450);
}
void NHD_i2c_lcd::moveCursor(byte direction, byte steps) {
Wire.beginTransmission(LCD_ADDR);
if (direction == 0) {
for (byte i = 0; i < steps; i++) {
Wire.write(PREFIX);
Wire.write(MOVE_CURSOR_LEFT);
}
if (cursorX - steps >= 0) cursorX -= steps;
else cursorX = 0;
} else {
for (byte i = 0; i < steps; i++) {
Wire.write(PREFIX);
Wire.write(MOVE_CURSOR_RIGHT);
}
if (cursorX + steps < 20) cursorX += steps;
else cursorX = 19;
}
Wire.endTransmission();
}
void NHD_i2c_lcd::moveDisplay(byte direction, byte steps) {
Wire.beginTransmission(LCD_ADDR);
if (direction == 0) {
for (byte i = 0; i < steps; i++) {
Wire.write(PREFIX);
Wire.write(MOVE_DISP_LEFT);
}
} else {
for (byte i = 0; i < steps; i++) {
Wire.write(PREFIX);
Wire.write(MOVE_DISP_RIGHT);
}
}
Wire.endTransmission();
}
void NHD_i2c_lcd::displayBaudRate() {
Wire.beginTransmission(LCD_ADDR);
Wire.write(PREFIX);
Wire.write(DISP_BAUD_RATE);
Wire.endTransmission();
}
void NHD_i2c_lcd::changeBaudRate(byte baudRate) {
Wire.beginTransmission(LCD_ADDR);
Wire.write(PREFIX);
Wire.write(baudRate);
Wire.endTransmission();
}
void NHD_i2c_lcd::displayI2Caddr() {
Wire.beginTransmission(LCD_ADDR);
Wire.write(PREFIX);
Wire.write(DISP_I2C_ADDR);
Wire.endTransmission();
}
void NHD_i2c_lcd::changeI2Caddr(byte addr) {
Wire.beginTransmission(LCD_ADDR);
Wire.write(PREFIX);
Wire.write(addr);
Wire.endTransmission();
}
void NHD_i2c_lcd::loadCustomChar(byte addr, byte bitmap[8]) {
Wire.beginTransmission(LCD_ADDR);
Wire.write(PREFIX);
Wire.write(addr);
for (int i = 0; i < 8; i++) {
Wire.write(bitmap[i]);
}
Wire.endTransmission();
}
uint8_t wordLength(char* start) {
uint8_t length = 0;
while (true) {
if (*start == ' ') break;
if (*start == '\0') break;
length++;
start++;
}
return length;
}