Distance sensor demo device

4. Software

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;

}