I2C for a small radio transmitter with a Panda

I’m trying to communicate with a radio transmitter that is working well for other things but has some additional functionality such as a temperature sensor on board that I want to access with I2C.

This is pretty much the sample code from the netmf book, cleaned up a bit to inline things more but I did try the original version as well with the same result. I’ve tried 100, 200, 400 and 4000 for the clock rate with no different. I always get back all 0s in the RegisterValue array. I tried sending an additional write command with question marks (the commented out line below) but it didn’t change anything. I did that because of a mysterious line in the radio manual, I’m including the relevant text from that as well in case I’m just interpreting the manual incorrectly. I also tried it as one write command, execd, then another write command for the question marks and a read, same result.


                //create I2C object
                I2CDevice.Configuration con = new I2CDevice.Configuration(0x48, 400);
                using (var i2c = new I2CDevice(con))
                {
                    byte[] RegisterValue = new byte[2];
                    var xActions = new I2CDevice.I2CTransaction[] 
                    {
                        I2CDevice.CreateWriteTransaction(Encoding.UTF8.GetBytes("QT")),
                        //I2CDevice.CreateWriteTransaction(Encoding.UTF8.GetBytes("???")),
                        I2CDevice.CreateReadTransaction(RegisterValue),
                    };

                    i2c.Execute(xActions, 1000);

Manual text is included here for convenience though formatting isn’t great, PDF manual can be found here https://www.argentdata.com/files/srb-mx146lv.pdf

I’m pretty sure I have the wires right, I have pins 1 & 2 going to Di 2 & 3 on my Panda and have tried swapping them just for good measure but they are matched up currently. Since the manual mentions the temp sensor itself has an address of 0x49 I tried that as well and it did return some numbers but they didn’t seem valid. Seems like it always returns two 80s or two 63s after trying to send various commands. Also not sure what commands the temp sensor would take on its own.

Is this device is 5V logick or 3.3V ?

I had I2C comunication problems when I tried to adress device with 5V logick. You then need level conversion circuit.

Hi,

This is a shot in the dark, but try 0x90 as the address…

Or 0x24 for that matter…

There is some abiguity in I2C if the address provided is already left shifted or not. And I can’t remember if the FEZ wants the address left shifted or not…

Thanks,
Errol

I2C addresses are 7 bit and FEZ/.netmf want it in that form so it would not be 0x90.
On the bus the first 8-bit value is the address and direction bit. The address being the first 7 bits and the direction (R/W) is the last bit. The R/W bit indicates which direction the I/O is to go with W=0 and R=1. So some spec may give the address in the form of that first 8-bit value.
Taking the example of the radio, 0x48 could be:
0x24 address and 0 write:
0100 100 – 0 = 0x48 write to address 0x24
0100 100 – 1 = 0x49 read from address 0x24. (I think that is what the last two lines of the document is talking about)
.Netmf takes care of constructing the first 8-bit value so it wants the device address.

The rule of thumb is that if the published address doesn’t work then shift it right 1 bit, 0x24.
Here’s a little tutorial on i2c that may be helpful:
I2C tutorial

BTW: I have not tried to use the FEZ with a multi master i2c device.

You should always check the return code of i2c.Execute. It tells you a lot !

i added some Wiki comments on 7-bit vs 8-bit addresses here [url]http://wiki.tinyclr.com/index.php?title=I2C_-_EEPROM[/url]

The device is 3.3V logic which is good since that is what comes out of Panda pins. I tried 0x24 which still returned all 0s and 0x90 which threw an error. The result from the Execute method was always 0. The strange thing is that 0x49 did return something so I’m going to look at the bits of these different numbers and read up on I2C and see if anything comes to me.

So in the datasheet for this device, the listed address is 0x48 and there is also a device listed at 0x49 (the temperature sensor).

0x48 = 1001000
0x49 = 1001001

Just to clarify here about addresses. Most datasheets will either list a correct I2C 7-bit address, or will list/discuss an 8-bit address amongst read and write operation examples. In the case of your device, the addresses 0x48 and 0x49 are the proper 7-bit addresses. The 8-bit address that would get pushed onto the wire would be:
0x48 device READ = 10010001 = 0x91
0x48 device WRITE = 10010000 = 0x90
0x49 device READ = 10010011 = 0x93
0x49 device WRITE = 10010010 = 0x92
You know they must be talking about the 7-bit address because there would be a conflict with the 0x48 and 0x49 addresses for two separate devices.

Can you show (and tell) us how it’s connected? The diagram on page 7 shows how I think it should be connected… I don’t know why they’re not explicit in how the SPI/FIX connection is wired in SPI/I2C mode rather than having it grounded like they do in tracker mode (I can only assume they have a pullup circuit in there so there’s no need to do it yourself)

Typically a return code of 0 means you aren’t finding the device on the bus. That means to me something is not connected. It’s also not clear from the data sheet whether the I2C temperature sensor will work independent of the mode that the radio is in - it seems to imply it might be; that might mean that I2C will work for it even tho the radio is in tracker mode and not responding. That’s why I suggest wiring is the area I’d double check…

I’ve checked the wiring a few times but just in case here is a list of all the connections I have made.So far all of the pins are pulled up, for example though undocumented, PTT is high to turn off and low to turn on. The transmitter itself works ifne and I can modulate a signal and hear it correctly so I should at least be close. I did try swapping SDA/SCL and I’ve also tried all the hex addresses mentioned so far, whether mentioned as definitely wrong or definitely right. :slight_smile: Queries on 0x49 do return some data (though I have no idea what the commands would be for that address) so that makes me think I have something right.

4 pins, power to 5V out, both grounds to ground, antenna sticking up in air

12 pins:
1 - Di3
2 - Di2
3 - NC
4 - Ground & NC (tried both)
5 - NC
6 - NC
7 - Ground & NC (tried both)
8 - Di13, PTT
9 - Di11, Ready signal
10 - NC
11 - Di10, modulation
12 - Ground

Ah, I got a good result! The guy I bought it from suggested I not send a write command and only a read and listen on the 0x49 port and that did work so tha tis probably what the manual meant for that. I would like to be able to send commands though to set the frequency used and adjust the memory channels but this is progress…

Ok, got other commands working as well by separating into two transactions. Came up with that idea after reading in doc that after getting a command, the next read would return the data. Not sure if that is what it meant but it seems to work. Below will display “MX146-LV”

            I2CDevice.Configuration con = new I2CDevice.Configuration(0x48, 400);
            using (var i2c = new I2CDevice(con))
            {
                byte[] RegisterValue = new byte[10];
                var xActions = new I2CDevice.I2CTransaction[] 
                {
                    I2CDevice.CreateWriteTransaction(Encoding.UTF8.GetBytes("QN")),
                };
                int result = i2c.Execute(xActions, 1000);
                if (result == 0) return;

                xActions = new I2CDevice.I2CTransaction[] 
                {
                    I2CDevice.CreateReadTransaction(RegisterValue),
                };
                result = i2c.Execute(xActions, 1000);

                Debug.Print(new String(Encoding.UTF8.GetChars(RegisterValue)));
            }