I2C Bus Device Detection – Execute Response not Zero if Device is not connected

Hi,

in a FEZ Panda II program, which bases on v4.0 framework, I have a simple routine to check, which PCF8574 are connected to the bus. I read a byte and if the Execute fails and returns zero bytes, the device is not connected:

            I2CDevice MyI2C = new I2CDevice(null);
            I2CDevice.I2CTransaction[] busTransaction;
            I2CDevice.Configuration BusConfig;

            for (byte i = 0; i < 16; i++)
            {
                byte BusAddress = HC.I2C.Devices.PCF8574.GetBusAddressFromNumber(i); // little function to return the bus address for the 16 possible PCFs
                byte[] PortValues = new byte[1];
                busTransaction = new I2CDevice.I2CTransaction[1];
                busTransaction[0] = I2CDevice.CreateReadTransaction(PortValues); // read one byte
                BusConfig = new I2CDevice.Configuration(BusAddress, 200);
                MyI2C.Config = BusConfig;
                int res = MyI2C.Execute(busTransaction, 4000);
                if (res > 0)
                {
                    Debug.Print("PCF8574 - " + i.ToString() + " found (" + PortValues[0].ToString() + ")");
                }
                else
                {
                    Debug.Print("PCF8574 - " + i.ToString() + " NOT found");
                }
            }

Now I’m using a RAPTOR and use the same code wic current framework, but if a device is not connected, the execute command although return 1 instead of 0. That seems to be wrong.

Does somebody knowns about any changed in the framework or is there another good idea to check whether a PCF device in a known address is connected to the bus?

Thanks

@ bin-blank - Could you try it with an EMX, G120, or Cerb by any chance?

No, I do not have such hardware available.

But you maybe can try to do it on any hardware you have available by writing a one byte read transaction to an address, which is not connected to the bus, e.g. without any devices connected to the bus.

The problem is, that I expect, that Execute returns zero, if there is no device-response on the bus. This is the case in older .NET Micro Framework version on Panda II. And it is absolutely possible to identify that a device does not response by the I2C protocol.

I mean to remember, that it worked well before last framework update on Raptor, too, but not sure, but anyway, it should work as expected at the current version.

Maybe somebody else can try these three lines of code, because there is no additional hardware needed. If it always returns a value higher than zero, there maybe is a bug, maybe not on GHI side.

@ bin-blank - We will take a look and see what we can find.

I do not have a lot of experiences with I2C on NETMF but I can confirm that I was also surprised that when I read bytes from PCF8574 on my FEZ Raptor(with last firmware) and I2C bus was not connected there wasn’t any exception. There was only exception when I made a write command to the device which was not connected.

@ mhstr: Yes, there is no Exception expected, but the return value of Execute shouldn’t be “1” it should be “0” because the device is not connected.

I also can’t through I2C to read/write NFC and I have no idea how to do.
My platform is NETMF and H/W is ST32F429I discovery board.
Terrible thing is I don’t have any sample code to build and porting.
I copy and re-edit code.
//================================================================
using System;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Input;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Hardware;

namespace MFTest
{
public class Program
{
public static void Main()
{

        //Cpu.Pin I2C_SCL;
        //Cpu.Pin I2C_SDA;



        
        //The PN532 is configured with I2C address 0x48 and is able to support a clock frequency up to 400 kHz.
        ushort I2C_ADDRESS = 0x38; 
        int I2C_CLOCK_RATE_KHZ = 400;
        
        I2CDevice conI2C = new I2CDevice(new I2CDevice.Configuration(I2C_ADDRESS, I2C_CLOCK_RATE_KHZ)); //Address is 0x38 @ 400KHZ clock
        
        // Create transactions
        // We need 2 in this example, we are reading from the device
        // First transaction is writing the "read command"
        // Second transaction is reading the data
        I2CDevice.I2CTransaction[] xActions = new I2CDevice.I2CTransaction[2];

        // create write buffer (we need one byte)
        byte[] RegisterNum = new byte[1] { 2 };
        xActions[0] = I2CDevice.CreateWriteTransaction(RegisterNum);
        // create read buffer to read the register
        byte[] RegisterValue = new byte[1];
        xActions[1] = I2CDevice.CreateReadTransaction(RegisterValue);

        // Now we access the I2C bus using a timeout of one second 
        // if the execute command returns zero, the transaction failed (this 
        // is a good check to make sure that you are communicating with the device correctly
        // and don't have a wiring issue or other problem with the I2C device)
        if (conI2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        else
        {
            Debug.Print("Register value: " + RegisterValue[0].ToString());
        }


        Debug.Print("\r\n------------------------------------------\r\n\r\n");

        /* Infinite loop */
        Thread.Sleep(Timeout.Infinite);
    }

    //--------------- Write to EEPROM -----------------------


}

}
//================================================================

But it always shows "Failed to perform I2C transaction"
I don’t know how to set my I2C1_SCL and I2C1_SDA pin
Can anyone help me?
Thanks…

Welcome thorne

I am betting you have the wrong I2C address. Do you know what the ACTUAL address is ? I can se in the code that there’s some inconsistencies in the comments and the actual code.



 //The PN532 is configured with I2C address 0x48 and is able to support a clock frequency up to 400 kHz.
 ushort I2C_ADDRESS = 0x38; 
 int I2C_CLOCK_RATE_KHZ = 400;

 I2CDevice conI2C = new I2CDevice(new I2CDevice.Configuration(I2C_ADDRESS, I2C_CLOCK_RATE_KHZ)); //Address is 0x38 @ 400KHZ clock

(note how my code looks different ? If you click the little pencil icon next to your post, and hit the 101010 button, you’ll get some code block markers you can put around your text :slight_smile: )

So the first comment says address is 0x48. The constant says its 0x38, and the I2C Device creation comment says 0x38. But here’s the thing. I2C in netmf uses the 7-bit address (not the 8-bit read or write addresses). I suspect your I2C address is actually meant to be 0x24 (which is the 7-bit i2c address of the common PN532 devices I just found, which talk about the 0x48 address)

Any more questions I reckon you should start your own thread, this one is pretty specific and your problem is more fundamental

I can confirm that on Cobra II [em]Execute[/em] method returns 0 when I2C slave device is not connected.

What do you want to do exactly ? by the way i wanna learn temperature with a fez panda 2 with i2c communication