HD-C0216CIZ-FSW-FBW-3V3 requires bit banging????
I have a HD-C0216CIZ-FSW-FBW-3V3 on an Arduino Uno with 4.7k pullup resistors to a 3.3V plane (same as VDD) for the I2C bus. I'm having trouble getting the display to actually show characters.
When I ran an example I found on these forums that used bit-banging on the I2C bus, that worked fine. However, when I instead attempt to use an I2C library to have that controlled by hardware, it isn't working correctly. I even modified the example to use the embeded I2C rather than bit-baning
********************************THIS WORKS************************************
unsigned char text1[]={"NEWHAVEN Display"};
unsigned char text2[]={"2x16 LCD Module "};
unsigned char text3[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
unsigned char text4[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
/*****************************************************/
#define SDO A4 //Serial data
#define SCLK A5 //Serial clock
#define RESET 13 //RESETET
/*****************************************************/
const char Slave = 0x7C;
const char Comsend = 0x00;
const char Datasend = 0x40;
const char Line2 = 0xC0;
/*****************************************************/
/*****************************************************/
void I2C_out(unsigned char j) //I2C Output
{
int n;
unsigned char d;
d=j;
for(n=0;n<8;n++){
if((d&0x80)==0x80)
digitalWrite(SDO, HIGH);
else
digitalWrite(SDO, LOW);
d=(d<<1);
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
digitalWrite(SCLK, LOW);
}
digitalWrite(SCLK, HIGH);
while(SDO==HIGH){
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
}
digitalWrite(SCLK, LOW);
}
/*****************************************************/
void I2C_Start()
{
digitalWrite(SCLK, HIGH);
digitalWrite(SDO, HIGH);
digitalWrite(SDO, LOW);
digitalWrite(SCLK, LOW);
}
/*****************************************************/
void I2C_Stop()
{
digitalWrite(SDO, LOW);
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
digitalWrite(SCLK, HIGH);
}
/*****************************************************/
void Show(unsigned char *text) // Display text
{
int n, d;
d=0x00;
I2C_Start();
I2C_out(Slave);
I2C_out(Datasend);
for(n=0;n<16;n++){
I2C_out(*text);
++text;
}
I2C_Stop();
}
/*****************************************************/
void nextline(void) // Move to Line 2
{
I2C_Start();
I2C_out(Slave);
I2C_out(Comsend);
I2C_out(Line2);
I2C_Stop();
}
void CGRAM (void)
{
I2C_Start();
I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x38); //go to instructino table 0
I2C_out(0x40); //Set CGRAM addRESETs to 0x00
I2C_Stop();
delay(10);
I2C_Start();
I2C_out(Slave);
I2C_out(Datasend);
I2C_out(0x00); //write to first CGRAM addRESETs
I2C_out(0x1E);
I2C_out(0x18);
I2C_out(0x14);
I2C_out(0x12);
I2C_out(0x01);
I2C_out(0x00);
I2C_out(0x00); //8 bytes per character
I2C_out(0x00);
//continue writing to remaining CGRAM if desired
I2C_Stop();
}
/****************************************************
* Initialization For ST7032i *
*****************************************************/
void init_LCD()
{
I2C_Start();
I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x38);
//delay(10);
I2C_out(0x39);
//delay(10);
I2C_out(0x14);
I2C_out(0x78);
I2C_out(0x5D);
I2C_out(0x6D);
I2C_out(0x0C);
I2C_out(0x01);
I2C_out(0x06);
//delay(10);
I2C_Stop();
//CGRAM(); //define CGRAM
I2C_Start();
I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x39);
I2C_out(0x01); //go back Home
I2C_Stop();
//delay(10);
}
/*****************************************************/
/*****************************************************/
void setup() {
pinMode(RESET, OUTPUT);
pinMode(SDO, OUTPUT);
pinMode(SCLK, OUTPUT);
digitalWrite(RESET, LOW);
delay(10);
digitalWrite(RESET, HIGH);
delay(100);
}
void loop() {
init_LCD();
//delay(2);
Show(text1);
nextline();
Show(text2);
delay(25000);
while(1){
digitalWrite(SDO, HIGH);
delay(1000);
}
}
****************************************THIS DOESN'T WORK********************************
#include <Wire.h>
unsigned char text1[]={"NEWHAVEN Display"};
unsigned char text2[]={"2x16 LCD Module "};
unsigned char text3[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
unsigned char text4[]={0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f};
/*****************************************************/
#define SDO A4 //Serial data
#define SCLK A5 //Serial clock
#define RESET 13 //RESETET
/*****************************************************/
const char Slave = 0x7C;
const char Comsend = 0x00;
const char Datasend = 0x40;
const char Line2 = 0xC0;
/*****************************************************/
/*****************************************************/
void I2C_out(unsigned char j) //I2C Output
{
Wire.write(j);
/*
int n;
unsigned char d;
d=j;
for(n=0;n<8;n++){
if((d&0x80)==0x80)
digitalWrite(SDO, HIGH);
else
digitalWrite(SDO, LOW);
d=(d<<1);
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
digitalWrite(SCLK, LOW);
}
digitalWrite(SCLK, HIGH);
while(SDO==HIGH){
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
}
digitalWrite(SCLK, LOW);
*/
}
/*****************************************************/
void I2C_Start()
{
Wire.beginTransmission(Slave);
/*
digitalWrite(SCLK, HIGH);
digitalWrite(SDO, HIGH);
digitalWrite(SDO, LOW);
digitalWrite(SCLK, LOW);
*/
}
/*****************************************************/
void I2C_Stop()
{
Wire.endTransmission();
/*
digitalWrite(SDO, LOW);
digitalWrite(SCLK, LOW);
digitalWrite(SCLK, HIGH);
digitalWrite(SCLK, HIGH);
*/
}
/*****************************************************/
void Show(unsigned char *text) // Display text
{
int n, d;
d=0x00;
I2C_Start();
//I2C_out(Slave);
I2C_out(Datasend);
for(n=0;n<16;n++){
I2C_out(*text);
++text;
}
I2C_Stop();
}
/*****************************************************/
void nextline(void) // Move to Line 2
{
I2C_Start();
//I2C_out(Slave);
I2C_out(Comsend);
I2C_out(Line2);
I2C_Stop();
}
void CGRAM (void)
{
I2C_Start();
//I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x38); //go to instructino table 0
I2C_out(0x40); //Set CGRAM addRESETs to 0x00
I2C_Stop();
delay(10);
I2C_Start();
//I2C_out(Slave);
I2C_out(Datasend);
I2C_out(0x00); //write to first CGRAM addRESETs
I2C_out(0x1E);
I2C_out(0x18);
I2C_out(0x14);
I2C_out(0x12);
I2C_out(0x01);
I2C_out(0x00);
I2C_out(0x00); //8 bytes per character
I2C_out(0x00);
//continue writing to remaining CGRAM if desired
I2C_Stop();
}
/****************************************************
* Initialization For ST7032i *
*****************************************************/
void init_LCD()
{
I2C_Start();
//I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x38);
//delay(10);
I2C_out(0x39);
//delay(10);
I2C_out(0x14);
I2C_out(0x78);
I2C_out(0x5D);
I2C_out(0x6D);
I2C_out(0x0C);
I2C_out(0x01);
I2C_out(0x06);
//delay(10);
I2C_Stop();
//CGRAM(); //define CGRAM
I2C_Start();
//I2C_out(Slave);
I2C_out(Comsend);
I2C_out(0x39);
I2C_out(0x01); //go back Home
I2C_Stop();
//delay(10);
}
/*****************************************************/
/*****************************************************/
void setup() {
Wire.begin();
pinMode(RESET, OUTPUT);
//pinMode(SDO, OUTPUT);
//pinMode(SCLK, OUTPUT);
digitalWrite(RESET, LOW);
delay(10);
digitalWrite(RESET, HIGH);
delay(100);
}
void loop() {
init_LCD();
delay(2);
Show(text1);
nextline();
Show(text2);
delay(25000);
while(1){
digitalWrite(SDO, HIGH);
delay(1000);
}
}
-
I believe I figured it out. Posting my findings to hopefully save someone else from the headache I just went through. The problem here is an inconsistency in I2C addressing.
The example I posted, as well as as the datasheet for the display state that the slave address is 0x7C. Normally, an I2C slave address is only 7-bits, and then an 8th Read/Write bit is appended to the end (1 for read, 0 for write). However, when looking carefully at the example and the datasheet, the slave address is actually 8 bits and includes the read/write bit within it.
Standard I2C libraries, when starting communication, will accept a 7-bit address, then bit shift left by 1 position, then append the Read/Write bit. So when using the "Wire.h" library in Arduino, when I call Wire.beginTransmission(0x7C), what ends up actually happening is the library starts by sending 0xF8 out on to the bus. (If I sent a Wire.requestFrom(0x7C, 3), it would start by sending 0xF9 onto the bus cause it appends a 1-read bit at the end).
So in short, in order to get standard I2C libraries to use this display, the actual slave that should be used is 0x3E. When I modiefied the non-working example above to instead useconst char Slave = 0x3E;
, it began working the same as the working example.
Though I do have a caveat to add. It seems that the SDO line must be kept low in order to actually display the characters. Otherwise you just get black boxes. I can work around this, but it's just an additional annoyance to deal with.0 -
Thanks for posting your solution as it may assist others with a similar issue.
Best Regards,0
Please sign in to leave a comment.
Comments
2 comments