N+2 I2C clock doesn't run - Netduino Plus 2 (and Netduino Plus 1) - Netduino Forums
   
Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

N+2 I2C clock doesn't run

I2C

  • Please log in to reply
4 replies to this topic

#1 justinbobo

justinbobo

    Member

  • Members
  • PipPip
  • 16 posts

Posted 29 January 2015 - 09:16 PM

I'm trying to command a EA DOGXL160 LCD display with my N+2 via I2C but I can't seem to get it to work. I've finally tried putting my scope on the SCL line and found that it just stays high. Based on another thread dealing with an unrelated issue, I tried this code:

 

OutputPort q = new OutputPort(Pins.GPIO_PIN_SCL, true);
            q.Write(false);
            q.Dispose();
 
and stepped through it. It does indeed go low on the second line, then goes back high after it's disposed. So I think that means my pullup resistors are okay since the Netduino CAN pull the clock line down, right? But FWIW, I have 4.7k resistors on there. (And I have tried commenting out those three lines in case they were somehow causing SCL to stay high after the OutputPort was disposed.) Just for grins, I tried swapping to 1k resistors because the datasheet for the display says there's already internal resistance ("600-100 ohm or more") on the I2C lines. Same result.
 
I've gotten I2C to work before on a N+2 with an expander (MCP23008 if I remember correctly) but I can't seem to find that code. I do recall running into issues with 4.1 firmware, but those problems were resolved when I flashed 4.2.2.2. I was still running 4.2.2.2 when I started troubleshooting this issue.
 
I have several N+2s lying around. I tried swapping them out in case it was a hardware issue. No dice.
 
I was originally using the I2CBus class. (2 reasons: that's what I got to work with the expander a year or two ago, and the display requires different I2C addresses for send/receive and command/data.) It would throw an exception when it tried to write the initialization commands. Stepping through the code, the exception was thrown when bytes written was 0. That's when I pulled out the scope.
 
So after getting nowhere with that other than finding that SCL wasn't moving, I decided to get rid of I2CBus and use MultiI2C from the NETMF toolbox. No change. (Well, now it no longer throws an exception when it tries to write, but according to the scope, it's not writing.)
 
Next, I tried upgrading everything from 4.2 to 4.3.1 and using VS Express 2012 instead of 2010. No change.
 
I also tried using A4/A5 instead of SDA/SCL with both firmware versions.
 
I'm assuming that the SCL line should be toggling all the time, but in case I'm wrong and it only runs when data is being sent, I put my Write command in a for loop that runs 100 times just to make sure that I wasn't just missing the change on my scope because it went by too quickly. I also tried hooking my scope up to the SDA line while it ran through that loop. Still just stayed high.
 
Here's my code. Removed unrelated variable declarations for clarity/readability. I left the for loop in there.
 
            OutputPort q = new OutputPort(Pins.GPIO_PIN_SCL, true);
            q.Write(false);
            q.Dispose();
            
            MultiI2C writeCommand = new MultiI2C(0x78);
            MultiI2C readStatus = new MultiI2C(0x79);
            MultiI2C writeData = new MultiI2C(0x7A);
            MultiI2C readData = new MultiI2C(0x7B);
 
            
            byte[] initialize = new byte[] { 0xF1, 0x67, 0xC0, 0x40, 0x50, 0x2B, 0xEB, 0x81, 0x5F, 0x89, 0xAF };
                    //These are all initialization commands from the datasheet
                    for (int i = 0; i < 100; i++)
                    {
                        writeCommand.Write(initialize);
                        Debug.Print(i.ToString());
                    }                   
 
I don't think it has anything to do with it, but in the interest of being thorough, here's the datasheet for the display: http://www.lcd-modul...dogxl160-7e.pdf

 

Sorry this is so long, just trying to give as much info as possible. Any ideas where I should go from here?



#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 31 January 2015 - 09:11 AM

Hi justinbobo,

With Netduino 2, the SDA/SCL pins take care of I2C traffic.

Please try using the regular I2C class first and see if that works. The SCL clock line will only be activated when data is being transmitted/received. You do need appropriately-sized pull-ups on the pin, for sure.

[Also...try detaching your device and JUST leaving the pull-ups on there. Do you see the clock signal then?]

Chris

#3 justinbobo

justinbobo

    Member

  • Members
  • PipPip
  • 16 posts

Posted 02 February 2015 - 03:57 PM

Well, that problem is fixed...sort of. The problem was really stupid, but I figure I should mention it here in case it happens to anyone else.

 

The problem? Bad jumper wire between my Netduino and my breadboard. I figured it out when I tried to disconnect/reconnect it from the Netduino while the program was running. Just putting a slight amount of pressure on it as I was grabbing it made the clock line show up on my scope right away. Swapped the jumper wire and everything is good.

 

I still don't understand how it was able to pull the line low when I deliberately wrote that to the OutputPort, but not when it was trying to do I2C comm. That's why I never bothered to check my connections.

 

The display still doesn't work, but it's the display's problem, not the Netduino's. I figured out it's not throwing SDA high for the Acknowledge bit. I did dig up my MCP23008 and hooked that into the breadboard on the same bus as the display. Using the same code, but just changing the address to 0x20, it does acknowledge. So I know my I2C bus setup is fine, e.g., pullup sizes, hi/lo voltages, etc.

 

I emailed the company (EA) to ask if they had any ideas. I just got an email back. The only possibly helpful suggestion he had was to try bitshifting the address from 0x78 = 0111 1000 to 0x3C = 0011 1100.

 

(His other advice was to make sure I was running at 100 kHz and to make sure my bus levels were H > 0.85 VDD and L < 0.15 VDD, which they are.)

 

I'll try that out when I get to work and let you all know if it works.

 

Also, when (if?) I get this working on I2C, I'll post the class I wrote for the DOGXL160. Nothing fancy, but it does include all 36 functions from the UC1610 datasheet. Probably save a couple hours of coding if you wanted to do the same thing.

 

Justin



#4 justinbobo

justinbobo

    Member

  • Members
  • PipPip
  • 16 posts

Posted 02 February 2015 - 04:01 PM

Oh and one more thing. Browsing through these threads, I wasn't certain which firmware versions I2C works on. So for anyone out there with the same question, my code works fine on both 4.2.2.2 and 4.3.1.0. I don't need to jumper to A4/A5 for either firmware version.



#5 justinbobo

justinbobo

    Member

  • Members
  • PipPip
  • 16 posts

Posted 05 February 2015 - 11:26 PM

I tried the bitshifting thing--and it worked! But now I have a new problem.

 

If I bitshift the four addresses (for read/write and command/data) given, I get this:

 

0x78 = 0111 1000 >> 0011 1100 = 0x3C

0x79 = 0111 1001 >> 0011 1100 = 0x3C

0x7A = 0111 1010 >> 0011 1101 = 0x3D

0x7B = 0111 1011 >> 0011 1101 = 0x3D

 

The display does acknowledge when I send to 0x3C and 0x3D...but I need four addresses, not two.

 

I wrote a loop to cycle through every possible I2C address. Those are the only two addresses that acknowledge.

 

I emailed the company, and this was the response I got:

 

"your compiler seems to do things automatically. The last bis is for write and read operation (pelase compare with I²C bus sepcification, done by Philips)"

 

Not sure what to make of that. But it seems apparent that the display is ignoring the first address bit. Is there some simple way to tell the Netduino to throw in an extra bit at the beginning?

 

It also seems apparent that this is an issue with the display. The expander is supposed to be addressed at 0x20, and it acknowledges at that address while on the same bus running the same program. Why would the display's address require a bit-shift but the expander's wouldn't? Seems like it's a problem with the display.

 

I've attached two screen shots from my scope, both named by the address used in the program. You can see that Attached File  0x78.bmp   219.43KB   0 downloads doesn't acknowledge and thus transmission is canceled. Attached File  0x3c.bmp   219.43KB   0 downloads does acknowledge and so another byte is transmitted.

 

But when I look at the scope readings, 0x3C looks like 0x78 to me. My understanding of I2C is that the master pulls the data line low to signify START, then the clock starts. The data line is read when the clock line is high. When I'm using the address 0x3C in code, the first high clock pulse has the data line at low, and the next 4 clock cycles, it's high. That sounds like 0111... to me, not 0011...

 

But I'm obviously missing something. If you look at attached file Attached File  0x20.bmp   219.43KB   2 downloads, that's the same setup trying to talk to the MCP23008 expander, whose address is 0x20, or 0010 0000. Same deal--that one looks an awful lot like 0100... rather than 0010... But it is acknowledging anyway.

 

I'm totally stumped here. Anyone have any ideas?







0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.