Page 1 of 1

Last I2C byte is ignored

Posted: Tue Mar 25, 2008 11:52 pm
by sthudium
I use the following C code but the last byte seems to be ignored. Instead of "Hello" the display is "Hell". Any ideas? Am I giving a proper STOP command?

Code: Select all

SDA = 0; // send Start 

sendByte( 0x50 ); // send address + read/*write = master writes 

sendByte( 0xFE ); // send LCD command prefix 
sendByte( 0x58 ); // send LCD clear screen command 

sendByte( 'H' ); // send ASCII 'H' 
sendByte( 'e' ); // send ASCII 'e' 
sendByte( 'l' ); // send ASCII 'l' 
sendByte( 'l' ); // send ASCII 'l' 
sendByte( 'o' ); // send ASCII 'o' 

SDA = 0; // setup Stop 
SCL = 1; 
delay(); 
SDA = 1; // send Stop 

Posted: Wed Mar 26, 2008 8:39 am
by Raquel
Hi sthudium,

I do not see a reason why 'Hell' would show and not 'o' on the screen. Have you checked the SCL and SDA lines? Do you see that you are sending a STOP prematurely? The STOP sequence in the code looks ok, but I am not sure about the START.

Clarification. please

Posted: Wed Mar 26, 2008 11:32 am
by sthudium
Thanks, Raquel, for your timely response. I really enjoy this prompt attention.

I have some questions, though, about your response.

I'm not certain I understand what you meant when you asked whether I checked the SCL and SDA lines. They obviously were working well enough to display "Hell". And, if I repeat the C code sequence the missing "o" momentarily appears before the old display is cleared and then replaced with another "Hell." Also, I can get the missing "o" to appear by following it with another byte (e.g., command prefix + send cursor home command). This behavior suggests to me that the LCD requires something to terminate the "Hello" text string, something more than only the STOP sequence. Does that make sense to you.

Not shown in the code for the START was SCL=1, which was set by the initialization. Is that what you were referring to when you mentioned you had doubts about the START sequence?

Thanks!!

Posted: Wed Mar 26, 2008 12:22 pm
by Raquel
Hi,
No problem, we are here to help, as much as we can.

Now I am thinking that you will need to listen to the ACKs of the display. I have a feeling that you are communicating with the display too fast too often that it has overrun the buffer. Simply adding a delay at the end of the STOP sequence, say 1ms and see if this helps.

The display will NAK bytes that it can not handle. When the host sees a NAK, it should issue a stop, give the display time to process (50ms should be enough) then re-try the byte that was NAK'd.

What I meant by checking out the SCL and SDA lines is to scope these lines out and see when you are ACK'd or NAK'd to have a feel for what is happening.

And yes, thanks for clarifying the START sequence.

What is a NAK

Posted: Wed Mar 26, 2008 1:04 pm
by sthudium
Thanks, Raquel.

What is a NAK? My understanding, which may be faulty, was that after the host sends the 8th bit, it toggles the SCL line 1->0->1 for a 9th clock cycle. The LCD then does an ACK by pulling SDA low during this cycle. However, since your I2C FAQ said that ACK's should be ignored, I ignored the ACK and began sending the next byte after the 9th clock cycle. In other words, I merely provided a single clock cycle between sending back-to-back data bytes.

Please tell me how I should process an ACK/NAK.

Thanks!!

Posted: Wed Mar 26, 2008 2:13 pm
by Raquel
Which MCU are you using?
Normally, the data sheets for the MCUs detail the I2C protocol, from addressing to acknowledgments.

Also, I would like to apologize for the I2C faq. As of the new generation of displays (those that use Atmel MCUs), the faq regarding ACKs does not apply anymore. I will update that page on our site.

For a quick ACK/NAK tutorial:
The 9th clock is provided by the master for the slave (or itself) to acknowledge the last 8 bits (associated with the first 8 clocks)
When the transaction is a write to the slave, the 9th clock is provided to the slave to indicate to the master that everything is ok, ie. ACK (a low on the 9th clock) otherwise, if there is a problem then a NAK is sent (a high on the 9th clock)
When the transaction is a read from the slave, the 9th clock is provided to the master to indicate if it wants to continue reading, a signal to the slave that the read is okay and that the master wants to read some more (ACK). If the master is done reading, it sends a NAK to the slave after the last byte read.

I hope this clears some things out, otherwise there are lots I2C documentation out there that you can check out.

You were right

Posted: Thu Mar 27, 2008 4:26 pm
by sthudium
My I2C communication link now works flawlessly. You were spot on when you told me to check the SCL and SDA lines. I examined the code and saw that the SCL/SDA timing for ACK slot was not correct. So, I cleaned up the code, and added code to process the ACK, which I previously ignored.

Thanks, again, Raquel, for all of your help -- and patience!!

Posted: Thu Mar 27, 2008 5:05 pm
by Raquel
Glad to hear things are working now.
You are most welcome!