I2C Display Module (NHD-C160100-DiZ) for DIY Scientific Calculator Help - Page 1
Forum section: electronics / projects

author: adept
author_rank: Regular Contributor
timestamp: June 23, 2015, 03:26:44 am
content: Good evening everybody reading,This is a project I've been developing for about 6 months. I am stuck because I can't get the display module (datasheet here) to work. I attached my schematic for the calculator and the schematic from the display module's datasheet.I believe that the issue is with the hardware. I have measured the voltages and I am not liking what I'm seeing. I will record all the voltages here.Pin No.SymbolExternal ConnectionFunctional DescriptionVoltage1CSBMPUActive Low chip select0.003 V2RSTMPUActive Low Reset signal1.216V3NC-No Connect1.172V4SCLMPUSerial clock input (requires pull-up)2.012V @31.61kHz5SDAMPUSerial data input (requires pull-up)2.136V @31.61kHz6VDDPower SupplyPower supply for LCD and logic (+3.0V)3.337V7VSSPower SupplyGround0.008V8VOUTPower SupplyConnect to 1uF cap to VSS or VDD0.898V9V4Power Supply1.0-2.2uF cap to Vss0.530V10V3Power Supply1.0-2.2uF cap to Vss0.645V11V2Power Supply1.0-2.2uF cap to Vss0.634V12V1Power Supply1.0-2.2uF cap to Vss0.025V13NC-No Connect0.451V14NC-No Connect0.503VIf this information helps, I am using a level shifting module I ordered offline fromhere. I made sure to wire it in the correct high voltage-low voltage configuration.And finally, if need be the code (almost straight from the datasheet) is here:Code:/*****************************************************/const char Slave = 0x7E; //slave address+Write bitconst char Comsend = 0x00;const char Datasend = 0x40;#define SDA A4 //One of the Arduino I2C ports#define SCL A5/******************************************************/void setup(){unsigned char text = {'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '\n'};init_LCD();Show(text);}// end setup/******************************************************/void loop(){//empty}// end Arduino loop/*****************************************************/void I2C_out(unsigned char j) //I2C Output{int n;unsigned char d;d=j;for(n=0;n<8;n++){//send 8 bitsif((d&0x80)==0x80) //get only the MSBdigitalWrite(SDA, HIGH); //if MSB = 1, then SDA=1else digitalWrite(SDA, LOW); //if MSB = 0, then SDA=0delayMicroseconds(10);d=(d<<1); //shift data byte leftdigitalWrite(SCL, LOW);delayMicroseconds(10);digitalWrite(SCL, HIGH); //clock in datadelayMicroseconds(10);digitalWrite(SCL, LOW);delayMicroseconds(10);}digitalWrite(SCL, HIGH);delayMicroseconds(10);while(digitalRead(SDA)==1){ //wait here until ACKdigitalWrite(SCL, LOW);delayMicroseconds(10);digitalWrite(SCL, HIGH);delayMicroseconds(10);}digitalWrite(SCL, LOW);}// end function I2C_out/*****************************************************/void I2C_Start(void){digitalWrite(SCL, HIGH);digitalWrite(SDA, HIGH);delayMicroseconds(10);digitalWrite(SDA, LOW);digitalWrite(SCL, LOW);delayMicroseconds(10);}// end function I2C_Start/*****************************************************/void I2C_Stop(void){digitalWrite(SDA, LOW);digitalWrite(SCL, LOW);delayMicroseconds(10);digitalWrite(SCL, HIGH);digitalWrite(SDA, HIGH);delayMicroseconds(10);}// end function I2C_Stop/*****************************************************/void Show(unsigned char *text){int n,i;char page=0xB0;//first pagefor(i=0;i<13;i++){//100 pixels = 12.5 pagesI2C_Start();I2C_out(Slave);I2C_out(Comsend);I2C_out(page);I2C_out(0x10); //column address Y9:Y6I2C_out(0x01);//column address Y5:Y2I2C_Stop();I2C_Start();I2C_out(Slave);I2C_out(Datasend);for(n=0;n<160;n++){I2C_out(*text);//send data 4 times for grayscalingI2C_out(*text);I2C_out(*text);I2C_out(*text);++text;//point to next byte of datadelay(10);}I2C_Stop();page++;//move to next page}}// end function Show/***************************************************** Initialization ******************************************************/void init_LCD(){I2C_Start();I2C_out(Slave);I2C_out(Comsend);I2C_out(0x48); //partial display duty ratioI2C_out(0x64); // 1/100 dutyI2C_out(0xA0); //ADC selectI2C_out(0xC8); //SHL selectI2C_out(0x44); //initial Com0 registerI2C_out(0x00); //scan from Com0I2C_out(0xAB); //OSC onI2C_out(0x26); //I2C_out(0x81); //set electronic volumeI2C_out(0x15); //vopcode=0x1CI2C_out(0x56); //set 1/11 biasI2C_out(0x64); //3xdelay(2);I2C_out(0x2C); //I2C_out(0x66); //5xdelay(2);I2C_out(0x2E); //delay(2);I2C_out(0x2F); //power controlI2C_out(0xF3); //bias save circuitI2C_out(0x00); //I2C_out(0x96); //frc and pwmI2C_out(0x38); //external modeI2C_out(0x75); //I2C_out(0x97); //3frc, 45 pwmI2C_out(0x80); //start 16 level grayscale settingsI2C_out(0x00); //I2C_out(0x81); //I2C_out(0x00); //I2C_out(0x82); //I2C_out(0x00); //I2C_out(0x83); //I2C_out(0x00); //I2C_out(0x84); //I2C_out(0x06); //I2C_out(0x85); //I2C_out(0x06); //I2C_out(0x86); //I2C_out(0x06); //I2C_out(0x87); //I2C_out(0x06); //I2C_out(0x88); //I2C_out(0x0B); //I2C_out(0x89); //I2C_out(0x0B); //I2C_out(0x8A); //I2C_out(0x0B); //I2C_out(0x8B); //I2C_out(0x0B); //I2C_out(0x8C); //I2C_out(0x10); //I2C_out(0x8D); //I2C_out(0x10); //I2C_out(0x8E); //I2C_out(0x10); //I2C_out(0x8F); //I2C_out(0x10); //I2C_out(0x90); //I2C_out(0x15); //I2C_out(0x91); //I2C_out(0x15); //I2C_out(0x92); //I2C_out(0x15); //I2C_out(0x93); //I2C_out(0x15); //I2C_out(0x94); //I2C_out(0x1A); //I2C_out(0x95); //I2C_out(0x1A); //I2C_out(0x96); //I2C_out(0x1A); //I2C_out(0x97); //I2C_out(0x1A); //I2C_out(0x98); //I2C_out(0x1E); //I2C_out(0x99); //I2C_out(0x1E); //I2C_out(0x9A); //I2C_out(0x1E); //I2C_out(0x9B); //I2C_out(0x1E); //I2C_out(0x9C); //I2C_out(0x23); //I2C_out(0x9D); //I2C_out(0x23); //I2C_out(0x9E); //I2C_out(0x23); //I2C_out(0x9F); //I2C_out(0x23); //I2C_out(0xA0); //I2C_out(0x27); //I2C_out(0xA1); //I2C_out(0x27); //I2C_out(0xA2); //I2C_out(0x27); //I2C_out(0xA3); //I2C_out(0x27); //I2C_out(0xA4); //I2C_out(0x2B); //I2C_out(0xA5); //I2C_out(0x2B); //I2C_out(0xA6); //I2C_out(0x2B); //I2C_out(0xA7); //I2C_out(0x2B); //I2C_out(0xA8); //I2C_out(0x2F); //I2C_out(0xA9); //I2C_out(0x2F); //I2C_out(0xAA); //I2C_out(0x2F); //I2C_out(0xAB); //I2C_out(0x2F); //I2C_out(0xAC); //I2C_out(0x32); //I2C_out(0xAD); //I2C_out(0x32); //I2C_out(0xAE); //I2C_out(0x32); //I2C_out(0xAF); //I2C_out(0x32); //I2C_out(0xB0); //I2C_out(0x35); //I2C_out(0xB1); //I2C_out(0x35); //I2C_out(0xB2); //I2C_out(0x35); //I2C_out(0xB3); //I2C_out(0x35); //I2C_out(0xB4); //I2C_out(0x38); //I2C_out(0xB5); //I2C_out(0x38); //I2C_out(0xB6); //I2C_out(0x38); //I2C_out(0xB7); //I2C_out(0x38); //I2C_out(0xB8); //I2C_out(0x3A); //I2C_out(0xB9); //I2C_out(0x3A); //I2C_out(0xBA); //I2C_out(0x3A); //I2C_out(0xBB); //I2C_out(0x3A); //I2C_out(0xBC); //I2C_out(0x3C); //I2C_out(0xBD); //I2C_out(0x3C); //I2C_out(0xBE); //I2C_out(0x3C); //I2C_out(0xBF); //I2C_out(0x3C); //end grayscale settingsI2C_out(0x38); //I2C_out(0x74); //I2C_out(0xAF); //display onI2C_Stop();}// end function init_LCD/*****************************************************/Thanks for taking the time to help,Stephen JenkinsSystem Operations EngineerWebsiteEmail

author: ale500
author_rank: Frequent Contributor
timestamp: June 23, 2015, 05:13:55 am
content: I have a couple of questions, check-list for you :- Why are you using 5 V to power the uC ? Many of those can be powered with 3.3 V. It may not run at 20 MHz, but when you need 20 MHz maybe another type of controller may be a better fit. I made my first functional calculator with an ATMega32, and getting the power down (~1 mA) means running at 1 MHz and a bit more sleep tricks, faster was not really needed, it depends on your algorithms.If your choice of 8 bit uC is size, it means not a huge battery too, wasting power on 5 V and 20 MHz... may not be the best fit.It also has an internal oscillator, you may not need an external crystal.- Does the I2C code work ? (Do you see your stream of data ?)- Do you see the correct start of transmission and acknowledge response from the display ?, I2C is open-drain, that means that when the LCD (and Memory chip) want to answer you have to set the pin to input, because the attiny doesn't (seem) to have open-drain output pins. (Not many level-converters support bidirectional operation...).

author: adept
author_rank: Regular Contributor
timestamp: June 23, 2015, 05:42:57 am
content: Thank you very much for your reply ale500. Here is a few answers you can take a look at.QuoteI have to run at 20 MHz. I wrote a custom 64 bit floating point math library for the uC but it runs pretty slow. I am using the ATTiny because I have a lot laying around and I am looking for a challenge.QuoteI see a waveform I can measure with my frequency counter in my multimeter but I don't have any other way to see if I have a proper data stream. That would be incredibly helpful if I did though.QuoteSupposedly the one I bought does. Is there a way to check for sure with a DMM? (I'm thinking maybe just tie the pins to the power supply and make a truth table.)And also I'm using an Arduino at the moment, not the ATTiny. I found it cumbersome to code on the ATTiny and run everything on it. Figured I'd keep the number of failure points lower that way too.

author: ale500
author_rank: Frequent Contributor
timestamp: June 23, 2015, 06:48:55 am
content: You may want to test your I2C code, having a second uC around can simplify the test. A multimeter is not the best test tool. Just write a receiver for i2c, and output the data via UART to the PC, so you can see what you are sending. Maybe you can invest a bit of money in a small logic analyzer, a 8 channel unit would do. That way you save loads of time.What do you mean with "pretty slow" ? does MUL take more than 1 second ? or does COS take more than 1 second ? Did you write it in assembler ?

author: eneuro
author_rank: Super Contributor
timestamp: June 23, 2015, 12:06:10 pm
content: Quote from: ale500 on June 23, 2015, 05:13:55 amI'd rather use first simple I2C RTC clock, which might be quite nice additional feature even in scientific calculator (eg. calculate sun position on the sky-do not ask why).Try to talk to something simply first than LCD.This what I've did sometime ag for MPu6050 I2C 3 axis accelerometer/gyro module I've made optoisolaed I2C interface betweem PC Linux serial port, so MPu side can be powered at any voltage including 3.3V or 5V , so now I can test I2C device directly from PC Linux with a few lines of C code, to ensure that there is no level shifting issues, etcBTW: Sometimes mistaken I2C address can ruin your day when working with I2C dongles, so ensure you have correct write/read I2C adresses implemented in your code, but I hope OP already did it and it is hardware issue not software

author: adept
author_rank: Regular Contributor
timestamp: June 23, 2015, 06:51:51 pm
content: QuoteWouldn't that require extra hardware to work? If not you should elaborate more because I would be interested.QuoteI got this from you too ale500. So in progress now is a little Arduino "logic analyzer" sketch. I'm going to use one of the many already available.QuoteYep, definitely have it right.QuoteI'm not sure of real time in terms of seconds. It's much faster than an entire second. I mean that it's slow in that it's about 30 lines of code for a 64 bit multiply. And it's written in C because it made it easier thanks to 64 bit integers being supported. If you want to see the code it'll be until I get home tonight.Now that I've answered those questions, does anybody know what voltages the built in LCD inverter outputs to those caps? I looked in the data sheet and can't find anything...

author: eneuro
author_rank: Super Contributor
timestamp: June 23, 2015, 11:26:12 pm
content: Quote from: adept on June 23, 2015, 06:51:51 pmI meant ensur efirst you have AVR ATTiny I2C software working with something else, eg. I2C RTC directly without any voltage shifting, so basicly use spare AVR, write a few lines of code to talk to RTC using your I2C AVR library (the same you use for I2C LCD), but take pull ups on breadboard or prototype PCB and connect I2C dongle without voltage level shifting, to ensure your I2C library on AVR is working, since you should be able to talko to other I2C device.Than replace it with LCD module run AVR at lower speed and 3.3V, so still no voltage level shifting and ensure first there is no bugs in software and everything works if connected directly only with pullup resistors for I2C

author: ale500
author_rank: Frequent Contributor
timestamp: June 24, 2015, 04:28:42 am
content: Exactly, make sure that the I2C code works first, for a test 3.3 V is not that bad. And make it work, make it fast, make it good is the strategy, I think, don't be concerned about the speed at this point, you may have to re-write a a portion in assembler anyways