Skip to content

Instantly share code, notes, and snippets.

@YuruPuro
Created June 11, 2023 01:06
Show Gist options
  • Save YuruPuro/b30ef9ae4f1c751aea37258bdc780697 to your computer and use it in GitHub Desktop.
Save YuruPuro/b30ef9ae4f1c751aea37258bdc780697 to your computer and use it in GitHub Desktop.
Sample to operate LCD1602/LCD2004 without using library
const int rs=2,rw=3,en=4 ;
int lcdPin[] = {10,11,12,13} ;
// make some custom characters:
byte heart[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000};
byte checkFig[8]={ 0b00001, 0b00011, 0b00111, 0b01111, 0b11111, 0b00100, 0b00010, 0b00001};
void lcdCommand(uint8_t value , uint8_t mode=LOW) {
digitalWrite(rs, mode);
digitalWrite(rw, LOW);
uint8_t wValue = value >> 4;
for (int i = 0; i < 4; i++) {
digitalWrite(lcdPin[i], (wValue >> i) & 0x01);
}
digitalWrite(en, LOW);
delayMicroseconds(100); // commands need > 37us to settle
digitalWrite(en, HIGH);
delayMicroseconds(1); // enable pulse must be >450ns
for (int i = 0; i < 4; i++) {
digitalWrite(lcdPin[i], (value >> i) & 0x01);
}
digitalWrite(en, LOW);
delayMicroseconds(100); // commands need > 37us to settle
digitalWrite(en, HIGH);
delayMicroseconds(1); // enable pulse must be >450ns
}
inline void lcdData(uint8_t value) { lcdCommand(value,HIGH) ; }
void lcdClear( ) {
lcdCommand(0x01);
delayMicroseconds(2000); // this command takes a long time!
}
void lcdStr(char *str) {
for (int i=0;str[i]!=0;i++) {
lcdData((uint8_t)str[i]) ;
}
}
void cursor(uint8_t col, uint8_t row) {
uint8_t pos = col ;
switch(row) {
case 0: pos = col ; break ;
case 1: pos = col + 0x40; break ;
case 2: pos = col + 20 ; break ;
case 3: pos = col + 20 + 0x40; break ;
default:pos = col ; break ;
}
lcdCommand(0x80 | pos); // SETDDRAM ADDR
}
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
lcdCommand(0x40 | (location << 3)); // SET CGRAMADDR : 8Byte Step
for (int i=0; i<8; i++) {
lcdData(charmap[i]);
}
}
// scroll Left
void scrollLeft(void) {
uint8_t cmd = 0x18 ; // CURSORSHIFT(0x10) | DISPLAYMOVE(0x08) | MOVELEFT(0x00)
lcdCommand(cmd);
}
// scroll Right
void scrollRight(void) {
uint8_t cmd = 0x1C ; // CURSORSHIFT(0x10) | DISPLAYMOVE(0x08) | MOVERIGHT(0x04)
lcdCommand(cmd);
}
void lcdInit( ) {
pinMode(rs, OUTPUT);
pinMode(rw, OUTPUT);
pinMode(en, OUTPUT);
for (int i=0; i<8; i++) {
pinMode(lcdPin[i], OUTPUT);
}
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50mS
delayMicroseconds(50000);
// Now we pull both RS and R/W low to begin commands
digitalWrite(rs, LOW);
digitalWrite(en, HIGH);
digitalWrite(rw, LOW);
// Send function set command sequence
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(150);
lcdCommand(0x02); // FUNCTIONSET
delayMicroseconds(150);
uint8_t cmd = 0x28 ; // FUNCTIONSET(0x20) | 4BIT MODE(0x00) | 2LINE(0x08) | 5x8DOTS(0x00)
lcdCommand(cmd); // FUNCTIONSET
// turn the display on with no cursor or blinking default
cmd = 0x0C ; // DISPLAYCONTROL(0x08) | DISPLAY ON(0x04) | CURSOR OFF(0x00) | BLINK OFF(0x00)
lcdCommand(cmd); // DISPLAYCONTROL
// clear it off
lcdClear( ); // clear display, set cursor position to zero
// Initialize to default text direction (for romance languages)
// set the entry mode
cmd = 0x06 ; // ENTRYMODESET(0x04) | ENTRY LEFT(0x02) | ENTRY SHIFT DECREMENT(0x00)
lcdCommand(cmd); // ENTRYMODESET
}
void setup() {
lcdInit( ) ;
createChar(1,heart) ;
cursor(0, 0);
lcdStr("Parallel 4 Bit") ;
cursor(0, 1);
lcdStr("NO Library \x01") ;
cursor(0, 2);
lcdStr("\xD5\xD9\xCC\xDF\xDB") ;
cursor(0, 3);
lcdStr(" I \x01 Arduino") ;
delay(5000) ;
}
void loop() {
for (int i=0;i<20;i++) {
scrollRight( ) ;
delay(500) ;
}
delay(2000) ;
for (int i=0;i<20;i++) {
scrollLeft( ) ;
delay(500) ;
}
delay(2000) ;
cursor(13, 1);
char work[16] ;
sprintf(work,"%d",millis() / 1000) ;
lcdStr(work) ;
}
// LCD1602A 8Bit parallel Interface SAMPLE
const int rs=2,rw=3,en=4 ;
int lcdPin[] = {6,7,8,9,10,11,12,13} ; // Connect D0 to D7 to Arduino pins 6 to 13.
// make some custom characters:
byte heart[8] = { 0b00000, 0b01010, 0b11111, 0b11111, 0b11111, 0b01110, 0b00100, 0b00000};
byte checkFig[8]={ 0b00001, 0b00011, 0b00111, 0b01111, 0b11111, 0b00100, 0b00010, 0b00001};
// Write command or data to LCD
void lcdCommand(uint8_t value , uint8_t mode=LOW) {
digitalWrite(rs, mode);
digitalWrite(rw, LOW);
for (int i = 0; i < 8; i++) {
digitalWrite(lcdPin[i], (value >> i) & 0x01);
}
digitalWrite(en, LOW);
delayMicroseconds(100); // commands need > 37us to settle
digitalWrite(en, HIGH);
delayMicroseconds(1); // enable pulse must be >450ns
}
// Write data to LCD
inline void lcdData(uint8_t value) { lcdCommand(value,HIGH) ; }
// Write strings to LCD
void lcdStr(char *str) {
for (int i=0;str[i]!=0;i++) {
lcdData((uint8_t)str[i]) ;
}
}
// Send claer command to LCD
inline void lcdClear( ) { lcdCommand(0x01); }
// Send cursor pos command to LCD
void cursor(uint8_t col, uint8_t row) {
uint8_t pos = col ;
switch(row) {
case 0: pos = col ; break ;
case 1: pos = col + 0x40; break ;
case 2: pos = col + 20 ; break ;
case 3: pos = col + 20 + 0x40; break ;
default:pos = col ; break ;
}
lcdCommand(0x80 | pos); // SETDDRAM ADDR
}
// Allows us to fill the first 8 CGRAM locations
// with custom characters
void createChar(uint8_t location, uint8_t charmap[]) {
location &= 0x7; // we only have 8 locations 0-7
lcdCommand(0x40 | (location << 3)); // SET CGRAMADDR : 8Byte Step
for (int i=0; i<8; i++) {
lcdData(charmap[i]);
}
}
// scroll Left
void scrollLeft(void) {
uint8_t cmd = 0x18 ; // CURSORSHIFT(0x10) | DISPLAYMOVE(0x08) | MOVELEFT(0x00)
lcdCommand(cmd);
}
// scroll Right
void scrollRight(void) {
uint8_t cmd = 0x1C ; // CURSORSHIFT(0x10) | DISPLAYMOVE(0x08) | MOVERIGHT(0x04)
lcdCommand(cmd);
}
// Initialize LCD
void lcdInit( ) {
pinMode(rs, OUTPUT);
pinMode(rw, OUTPUT);
pinMode(en, OUTPUT);
for (int i=0; i<8; i++) {
pinMode(lcdPin[i], OUTPUT);
}
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50mS
delayMicroseconds(50000);
// Now we pull both RS and R/W low to begin commands
digitalWrite(rs, LOW);
digitalWrite(en, HIGH);
digitalWrite(rw, LOW);
// Send function set command sequence
lcdCommand(0x30); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x30); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x30); // FUNCTIONSET
delayMicroseconds(150);
uint8_t cmd = 0x38 ; // FUNCTIONSET(0x20) | 8BIT MODE(0x10) | 2LINE(0x08) | 5x8DOTS(0x00)
lcdCommand(cmd); // FUNCTIONSET
delayMicroseconds(150);
// turn the display on with no cursor or blinking default
cmd = 0x0C ; // DISPLAYCONTROL(0x08) | DISPLAY ON(0x04) | CURSOR OFF(0x00) | BLINK OFF(0x00)
lcdCommand(cmd); // DISPLAYCONTROL
// clear it off
lcdClear( ); // clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
// Initialize to default text direction (for romance languages)
// set the entry mode
cmd = 0x06 ; // ENTRYMODESET(0x04) | ENTRY LEFT(0x02) | ENTRY SHIFT DECREMENT(0x00)
lcdCommand(cmd); // ENTRYMODESET
}
void setup() {
lcdInit( ) ;
createChar(1,heart) ;
cursor(0, 0);
lcdStr("Parallel 8 Bit") ;
cursor(0, 1);
lcdStr("NO Library \x01") ;
cursor(0, 2);
lcdStr("YuruPuro") ;
cursor(0, 3);
lcdStr(" I \x01 Arduino") ;
delay(5000) ;
}
void loop() {
for (int i=0;i<20;i++) {
scrollRight( ) ;
delay(500) ;
}
delay(2000) ;
for (int i=0;i<20;i++) {
scrollLeft( ) ;
delay(500) ;
}
delay(2000) ;
cursor(13, 1);
char work[16] ;
sprintf(work,"%d",millis() / 1000) ;
lcdStr(work) ;
}
#include <Wire.h>
#define I2C_ADDR 0x27
// ----- I2C -> Parallel BIT -----
#define Bl B00001000 // Back Light
#define En B00000100 // Enable bit
#define Rw B00000010 // Read/Write bit
#define Rs B00000001 // Register select bit
// ----- I2C -----
// コマンドを送信
void I2CSend(uint8_t data) {
Wire.beginTransmission(I2C_ADDR);
Wire.write(data);
Wire.endTransmission();
}
uint8_t I2CRead( ) {
Wire.requestFrom(I2C_ADDR, 1);
while (Wire.available() == 0 ) {}
uint8_t data = Wire.read();
return data ;
}
// write either command or data
void lcdCommand(uint8_t value, uint8_t mode=LOW) {
uint8_t dataH=value&0xf0;
uint8_t dataL=(value<<4)&0xf0;
mode = (mode == LOW) ? 0x00 : Rs ;
uint8_t data = (dataH|mode|Bl)|En ; // En HIGH
I2CSend(data) ;
delayMicroseconds(1); // enable pulse must be >450ns
data = (dataH|mode|Bl)&~En ; // En LOW
I2CSend(data) ;
delayMicroseconds(50); // commands need > 37us to settle
data = (dataL|mode|Bl)|En ; // En HIGH
I2CSend(data) ;
delayMicroseconds(1); // enable pulse must be >450ns
data = (dataL|mode|Bl)&~En ; // En LOW
I2CSend(data) ;
delayMicroseconds(50); // commands need > 37us to settle
}
inline void lcdData(uint8_t value) { lcdCommand(value,HIGH) ; }
inline void lcdClear( ) { lcdCommand(0x01); }
void lcdStr(char *str) {
for (int i=0;str[i]!=0;i++) {
lcdData((uint8_t)str[i]) ;
}
}
void cursor(uint8_t col, uint8_t row) {
uint8_t pos = col ;
switch(row) {
case 0: pos = col ; break ;
case 1: pos = col + 0x40; break ;
default:pos = col + 0x40; break ;
}
lcdCommand(0x80 | pos); // SETDDRAM ADDR
}
void lcdInit( ) {
// before sending commands. Arduino can turn on way before 4.5V so we'll wait 50mS
delayMicroseconds(50000);
// Send function set command sequence
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(4500); // wait more than 4.1ms
lcdCommand(0x03); // FUNCTIONSET
delayMicroseconds(150);
lcdCommand(0x02); // FUNCTIONSET
delayMicroseconds(150);
uint8_t cmd = 0x28 ; // FUNCTIONSET(0x20) | 4BIT MODE(0x00) | 2LINE(0x08) | 5x8DOTS(0x00)
lcdCommand(cmd); // FUNCTIONSET
// turn the display on with no cursor or blinking default
cmd = 0x0C ; // DISPLAYCONTROL(0x08) | DISPLAY ON(0x04) | CURSOR OFF(0x00) | BLINK OFF(0x00)
lcdCommand(cmd); // DISPLAYCONTROL
// clear it off
lcdClear( ); // clear display, set cursor position to zero
delayMicroseconds(2000); // this command takes a long time!
// Initialize to default text direction (for romance languages)
// set the entry mode
cmd = 0x06 ; // ENTRYMODESET(0x04) | ENTRY LEFT(0x02) | ENTRY SHIFT DECREMENT(0x00)
lcdCommand(cmd); // ENTRYMODESET
}
void setup() {
Serial.begin(9600) ;
Wire.begin( ) ;
lcdInit( ) ;
cursor(0, 0);
lcdStr("I2C 4 Bit") ;
cursor(0, 1);
lcdStr("NO Library") ;
delay(5000) ;
cursor(0, 0);
uint8_t data = I2CRead( ) ;
Serial.println(data,HEX) ;
}
void loop() {
cursor(11, 1);
char work[16] ;
sprintf(work,"%d",millis() / 1000) ;
lcdStr(work) ;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment