I2C, hard time getting it working

@ Brett - well, even before I read the Arduino article, just by reading the documentation for the chip, I put together the 0’s and 1’s and assumed there should be an missing 0 I front to get the 8 bits - thereby getting the wrong address just because I misinterpreted the information from about I2C in the article under help on this site. I was sure there had to be 8 bits as we always talk about 8bits/1byte in context of computers. That’s why the article I linked to was so helpful, because it explained the stuff about people thinking wrong about it - even chip makers when they write documentation. And it also tells you how you could spot the errors in addresses.

But the 7-bit versus 8-bit information is explicitly called out in here
https://www.ghielectronics.com/docs/12/i2c at least twice. Propose a change, lets see how we can make it better?? I agree, lets try to make it crystal clear

There are 3 lines of information about a topic that 100% of users fail to understand.

I really don’t understand this good enough (yet) to come up with a good recipe. But it’s clear that something needs to be rewritten. I know from other areas that it’s hard to write basic documentation about stuff you know well, because you take for granted much of the basic knowledge you have - witch is essential to get this up and running.

I don’t understand this…

Spawning off a simple background thread and trying different addresses should eventually find the chip(s)… but it’s a no-go. Anyone care to enlighten me?

Code used:


        void ProgramStarted()
        {
            Debug.Print("Program Started");

            GT.Timer timer1 = new GT.Timer(500);
            timer1.Tick += timer1_Tick;
            timer1.Start();

            Thread t1 = new Thread(new ThreadStart(ThreadStartT1));
            t1.Start();
        }

        void timer1_Tick(GT.Timer timer)
        {
            // pulse debug led to show signs of life
            this.PulseDebugLED();
        }

        ushort ta = 0x00;

        private void ThreadStartT1()
        {
            I2CDevice.Configuration config = null;
            I2CDevice device = null;

            while (true)
            {
                if (ta > 0xFF) ta = 0x00;

                config = null;
                device = null;

                char_Display.Clear();

                char_Display.PrintString("addy: 0x" + ta.ToString("X2"));
                char_Display.SetCursor(1, 0);

                try
                {
                    config = new I2CDevice.Configuration(ta, 100);
                    if (config == null) char_Display.PrintString("config == null");
                    Thread.Sleep(5);

                    device = new I2CDevice(config);
                    if (device == null) char_Display.PrintString("device == null");
                    Thread.Sleep(5);

                    var result = device.GetRegisters(config, 500, 0x00, 2);

                    char_Display.PrintString("result.len: " + result.Length);
                    char_Display.SetCursor(1, 0);
                    char_Display.PrintString("0: " + result[0].ToString());
                    char_Display.SetCursor(1, 8);
                    char_Display.PrintString("1: " + result[1].ToString());

                    if (result[0] != 0 && result[1] != 0)
                    {
                        char_Display.SetCursor(0, 14);
                        char_Display.PrintString("OK");
                        break;
                    }
                }
                catch
                {
                    char_Display.PrintString("cfg=" + (config == null ? "null " : "obj "));
                    char_Display.PrintString("dev=" + (device == null ? "null"  : "obj" ));
                }

                ta++;

                Thread.Sleep(100);
            }

            while (true)
            {
                char_Display.Clear();

                var result = device.GetRegisters(config, 500, 0x00, 2);

                char_Display.PrintString("result.len: " + result.Length);
                char_Display.SetCursor(1, 0);
                char_Display.PrintString("0: " + result[0].ToString());
                char_Display.SetCursor(1, 8);
                char_Display.PrintString("1: " + result[1].ToString());

                Thread.Sleep(1000);
            }
        }

It newer gets out of the first loop… it can sit forever, but it does throw an InvalidOperationException every time it tries to create a new Device…

If Config is null wouldnt you want to go to the next address without hitting device = new I2CDevice(config); ?

@ Justin - well, yes. But config is always an object, so that is not an issue here, but in production code, then you are right. It’s always the code that creates a new device that fails…

Call Dispose on previous device, before creating a new one.

On a second thought, create I2CDevice instance once and just switch the Config property every time you are trying a new address. This is the way you supposed to work with I2C bus and multiple devices anyways.

@ Architect - disposing it before recreating did the trick ;D

Testing 3 different sensors:

I do not see the GetRegisters method:
var result = device.GetRegisters(config, 500, 0x00, 2);

I have not upgraded to sdk package R3 yet. Is this method in the new sdk?

@ Bill_Wyo - ExtentionMethod :wink:

@ danibjor - Glad you got it working. Switching the Config is still a more proper way of doing it. :wink:

@ Architect - thanks for all the help! I just needed to get this think working - just a single sign of life is enough to get the faith back in this stuff :smiley:

I guess I should rewrite it (the right way) to a proper driver now as I got the basics in place.

You are welcome!

Cleaned up the code and made a gadgeteer driver out of all this mess. It’s to be found here: https://www.ghielectronics.com/community/codeshare/entry/827

Good job!