I2C, hard time getting it working

I have a couple of TMP75 sensors. On chip digital temperature sensor with two wire interface.

You would think it should be straight forward getting this baby to talk to the Cerb main board…

I tried to follow the help vide over here https://www.ghielectronics.com/docs/12/i2c - and I’ve been peeking on the source code for other modules, but I cannot get it to play ball.

I think I have the right address, and even did a for/loop with address 0x00 → 0xFF and having it try to connect to the different addresses.

The socket output states Socket 1 and 2 should support I2C, and I’ve been trying both ports with no luck what so ever. https://www.ghielectronics.com/docs/47/cerberus-developer

I’m using the break out module to connect to the chip, and I have checked and re-checked that the connections are correct according to the pin-out on the socket and the pins on the sensor. I have tried different chips, just in case one might be faulty.

No matter what I do, all i get is InvalidOperationException when it tries to create the I2CDevice…

Any suggestions?

Can you please show your code?

Sure…

Driver code:

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

namespace TI.TMP75
{
    public class TemperatureSensor : IDisposable
    {
        // Set Constants for Address and Clock Frequency
        const ushort TMP75_ADDRESS = 0x48;
        const int    CLOCK_FREQ = 4;
        const int    DELAY = 50;

        //Write Buffer
        byte[] configBytes = new byte[] { 0x01, 0x60 }; 
        byte[] readBytes  = new byte[] { 0x00 };

        //Read Buffer
        byte[] inBuffer = new byte[2];

        //Init I2C Device Config
        I2CDevice.Configuration config = new I2CDevice.Configuration(TMP75_ADDRESS, CLOCK_FREQ);

        //Init I2C Device & Read/Write Transactions
        I2CDevice sensor;
        I2CDevice.I2CWriteTransaction configTrans;
        I2CDevice.I2CWriteTransaction writeTrans;
        I2CDevice.I2CReadTransaction  readTrans;

        public TemperatureSensor()
        {
            Init();
        }

        public TemperatureSensor(ushort tmp75_address)
        {
            this.config = new I2CDevice.Configuration(tmp75_address, CLOCK_FREQ);
            
            Init();
        }

        private void Init()
        {
            this.sensor = new I2CDevice(config);

            if (sensor == null) return;

            this.configTrans = I2CDevice.CreateWriteTransaction(configBytes);
            this.writeTrans  = I2CDevice.CreateWriteTransaction(readBytes);

            this.readTrans   = I2CDevice.CreateReadTransaction(inBuffer);

            I2CDevice.I2CTransaction[] transactions = new I2CDevice.I2CTransaction[] { configTrans };
            this.sensor.Execute(transactions, DELAY);
        }

        public void Dispose()
        {
            this.sensor.Dispose();
            this.config = null;
            this.configTrans = null;
            this.writeTrans = null;
            this.readTrans = null;
        }

        public int ReadTemperature()
        {
            if (sensor == null) return -1;

            I2CDevice.I2CTransaction[] transactions = new I2CDevice.I2CTransaction[] { writeTrans, readTrans };

            this.sensor.Execute(transactions, DELAY);

            return (inBuffer[0] * 256) + inBuffer[1];
            
            // int   value = (inBuffer[0] * 256) + inBuffer[1];
            // float temp  = ((float)value * (float)0.0625);

            // return temp;
        }
    }
}

I’ve also been peeking at this Arduino code, but I can’t seem to get to the point where i have an I2C object to start querying the chip…

http://playground.todo.arduino.cc/en/Main/TMP75I2CThermometerCode

code that calls the chip driver

        ushort addy = 0x00;

        void timer2_Tick(GT.Timer timer)
        {
            timer.Stop();

            addy++;

            if (addy > 0xFF) addy = 0x40;

            var res = readTemp(addy);

            if (res) addy--;

            timer.Start();
        }

        private bool readTemp(ushort addy)
        {
            try
            {
                char_Display.Clear();
                char_Display.PrintString("Sensor @ 0x" + addy.ToString("X2"));
                char_Display.SetCursor(1, 0);

                var sensor = new TemperatureSensor(addy);

                char_Display.PrintString("temp: " + sensor.ReadTemperature().ToString());

                Thread.Sleep(5000);

                return true;
            }
            catch (Exception ex)
            {
                char_Display.PrintString("crap!");
                throw ex;
            }

            return false;
        }


I have been looking at the I2C code as well. I am trying to talk to a MLX90614ESF-BAA infrared thermometer. I am connected to pins 8 and 9 on socket 2. I don’t understand why the code does not require the pins to be defined as they are in the code at https://www.ghielectronics.com/community/codeshare/entry/236

If you are generating I2C in Software then you need to specify the pins but if you are using the built in Hardware then the pins are predefined.

danibjor says he has tried both Sockets 1 and 2. Which socket is the built in Hardware supporting.

@ danibjor - how A0 A1 A2 are connected on the sensor?

On my last attempt, All grounded.

The sensors all come from an old iMac. They are all on a small PCB like this.

Only v+ gnd clock and data are connected to the socket. But as they all worked in the iMac, I guess there should be no problems with the board nor the sensors…

Edit: the Arduino community says all these sensors are wired up with address 0x48 and 0x49 - and they work fine with Arduino boards, so I see no problem using it with our stuff…

1 Like

Your clock frequency is wrong.

I’ve tried both 1, 4 and 400khz… And a few others in between…

Try 100.

OK, tried 100… Now it loops trough address 0x40 to 0x4F, starts back at 0x40 and this time when it gets up to 0x4B (tried a new sensor) - this time it connects.

Reading out values only returns 0x0 and 0x0 for the two bytes i get back from the sensor… but it’s getting closer now.

Where did you find the 100 value? Tought the sensor was set default to 400…

Sensor supports wide range of frequencies, indeed. Hardware I2C on MCU can only do certain frequencies. 100 is a safe bet. With all address pins grounded 0x48 is the address you should use.

1 Like

@ Architect - ok. I’ll take a note on 100 for future stuff. Thanks :slight_smile:

I tried another sensor board this last time. Not what address it is set up with, but I somewhat get connected with 0x4B on this one. Guess it’s logical that every sensor on the computer have its own address.

I’ll dig some more and try and actually get a temperature reading. 0C seems a little cold for indoor, even tough it’s winter outside :stuck_out_tongue:

Btw +1 on recycling the sensor.

I’d also suggest 0x48 and 0x49 are not the right addresses to look at. Remember, 100% of I2C issues we see here are people using the 8-bit address for a device when netmf needs the 7-bit address. (this one could be the exception ! :slight_smile: ) The Arduino crowd usually quote the 8-bit address (and when you said 0x48 and 0x49, that’s usually a sign of this!)

https://www.ghielectronics.com/docs/12/i2c

You’ve found 0x4b which actually makes a lot of sense of being in the same address “family” of 0b1001 and different a0/a1/a2 lines; that’s a range of options of 0x48 to 0x4f.

I +1 the recycle too, awesome !

1 Like

@ Brett - that 7/8-bit address stuff clarifies a lot. If more then me have problems, and also this seems to be a common problem, maybe some more info to enlighten people should be added to the documentation.

Found some useful information here about the topic, at least I feel I understand it better after reading it… http://www.totalphase.com/support/kb/10039/

@ Architect - thanks! Half the fun is to see what you can do with the stuff you have, not just running around buying new all the time.

I got some interesting chips lying around here on my desk that needs drivers - but that will come when I understand the topic of I2C better.

Cool, so the 100% rule still stands :slight_smile: :slight_smile:

Yes, the “confusion” is prevalent, but the problem is that although the original Phillips documentation calls out a 7-bit address, there are many other places that talk about the full 8-bit read or write addresses that won’t change their ways, will continue to litter the interwebs with their false information, and will make it hard for someone coming at this with not a huge amount of information to struggle, or worse follow the “trend” and be wrong as well. Yes, I’m pointing at you, Arduino. :wink: Seriously though, it’s hard to make sure everything talks about this correctly since different libraries use different “base” address (and in the case of Arduino, from what I understand, that’s not the defined-by-the-standard address) and the people using those libraries will only talk about the address in their own context.

1 Like